//
// Cheese Framework 0.98
//
// Copyright 2010, Licensed under the MIT license.
// http://innovator.samsungmobile.com/
//

/* @Framework_Ver 0.98 */

(
function(window) {

//d var widget = undefined;

// Cheese Global Object
var CheeseGlobal = new (function()
{
	this.buffer = new Array();
	this.bufferID = 0;
	this.prefixBufferClass = "CheeseBufferClassData";
	this.prefixBufferID = "CheeseBufferID-";	
	this.timerList = new Array(); // timer list
	this.queueList = new Array();
	this.pop = "";
	this.sceneStack = new Array();
		
	this.transEffect = "slideHor";
	this.transSecond = "0.5s";
	this.transMotion = "ease";
	this.popTransEffect = "pop";
	this.popTransSecond = "0.5s";
	this.popTransMotion = "ease";

	this.transDirection = "on";

	this.softkeyType = "type1";
	this.softkeyFunc = null;
	this.softkeyData = null;

	this.softkeyDataGlobal = null;
	this.softkeyFuncGlobal = null;
	this.softkeySetListData = null;
	this.softkeySetListFunc = null;
	this.setListSelectData = null;
	this.storageDate = null;

	this.pageCache = false;
	this.name = "NoName";
	this.theme = "";
	this.reduceStringNum = 20;
	
	this.widgetIdleWidth = 200;
	this.widgetIdleHeight = 100;
	this.eventType = null;
	this.tabPageTimming = "after";
	
	this.$ = window.$;
	
	// constants
	this.AJAXREADYSTATE = {
		//d 0: The request is uninitialized (before you've called open()).
		//d 1: The request is set up, but not sent (before you've called send()).
		//d 2: The request was sent and is in process (you can usually get content headers from the response at this point).
		//d 3: The request is in process; often some partial data is available from the response, but the server isn't finished with its response.
		//d 4: The response is complete; you can get the server's response and use it.
		"UNINIT"		: 0,
		"NOTSENT"		: 1,
		"SENDING"		: 2,
		"RECEIVING"		: 3,
		"DONE"			: 4
	};
	
	this.EVENTSTRING = {
        FLICK_LEFT :    "FLICKLEFT"     ,
        FLICK_RIGHT :   "FLICKRIGHT"    ,
        FLICK_UP :       "FLICKUP"      ,
        FLICK_DOWN :     "FLICKDOWN"    ,
        DRAG :           "DRAG"			,
        DRAG_DROP : 	 "DRAGDROP"   	,
        SWIPE :		     "SWIPE"		,
        TAP :            "TAP" 			,
        LONG_TAP :       "LONGTAP"     	,
        DOUBLE_TAP :     "DOUBLETAP"   	,
        TOUCH_START :    "TOUCHSTART"   ,
        TOUCH_MOVE :     "TOUCHMOVE"   	,
        TOUCH_END :      "TOUCHEND"
    };
	this.TouchTimer = {
        FLICK : 1000,
	    doubleTap : 300,
	    longTap : 1000    
    };
})();

var Cheese = function( _s ) {
	return new Cheese.fn.selector( _s );
};

Cheese.fn = Cheese.prototype = {

	// selector
	//
	// parameters
	//  function
	//    register load function
	//  DOM object
	//    wrap component object
	//  string
	//    find DOM objects
	selector : function ( _s )
	{
		var cArray;

		// argument : function
		if( !_s )
	    {
			cArray = new Array();
		}
		else if( typeof _s == "function" )
		{
			Cheese.load( _s );
			return;
		}
		// argument : DOM object
		else if ( _s == window || _s == document || _s.nodeType )
		{
			cArray = new Array();
			cArray[0] = _s;
		}
		else if( typeof _s == "object" )
		{
			cArray = _s;
		}
		// else search dom elements
		else
		{
			cArray = document.querySelectorAll(_s);
		}

		this.componentContext = this.contextToComponent(cArray);
		this.length = this.componentContext.length;

		return this;
	},

	// contextToComponent
	//
	// parameters
	//   array of DOM element object
	// return
	//   array of component object
	contextToComponent : function ( _cArray )
	{
		var rArray = new Array();

		for ( var i = 0; _cArray[i]; i++ )
		{
			var c = _cArray[i];
			var id = _cArray[i].id;
			var classname = " " + _cArray[i].className + " ";

			// component categorization
			if ( classname )
			{			
				if ( classname.indexOf(" title ") != -1 )
					rArray[i] = new CheeseTitle( c );
				else if ( classname.indexOf(" setTitle ") != -1 )
					rArray[i] = new CheeseSetTitle( c );
				else if ( classname.indexOf(" setList ") != -1 )
					rArray[i] = new CheeseSetList( c );		
				else if ( classname.indexOf(" list ") != -1 )
					rArray[i] = new CheeseList( c );		
				else if ( classname.indexOf(" googleMap " ) != -1 )
				    rArray[i] = new CheeseGoogleMap ( c );		
				else if ( classname.indexOf(" chart " ) != -1 )
				    rArray[i] = new CheeseChart ( c );		
				else if ( classname.indexOf(" softkey ") != -1 )
					rArray[i] = new CheeseSoftkey( c );
				else if ( classname.indexOf(" popup ") != -1 )
					rArray[i] = new CheesePopup( c );
				else if ( classname.indexOf(" scene ") != -1 )
					rArray[i] = new CheeseScene( c );
				else if ( classname.indexOf(" tab ") != -1 )
					rArray[i] = new CheeseTab( c );
				else if ( classname.indexOf(" busyIndicator ") != -1 )
					rArray[i] = new CheeseBusy( c );
				else if ( classname.indexOf(" pageControl ") != -1 )
					rArray[i] = new CheesePageControl( c );
				else if ( classname.indexOf(" rssTime ") != -1 )
					rArray[i] = new CheeseRSSTime( c );
				else if ( classname.indexOf(" btn ") != -1 )
					rArray[i] = new CheeseButton( c );

			}
			
			if( !rArray[i] )
				rArray[i] = new CheeseBasic( c );
		}

		return rArray;
	},

	// size
	// 
	// return
	//    the number of components
	size : function ()
	{
		return this.length;
	},

	// each
	//   Iterate over a Cheese object, executing a function for each matched element.
	//
	// example
	//   .each( function ( index ) { ... } )
	each : function( _func )
	{
		for (var k = 0; this.component(k); k++ )
			_func.call( this.dom(k), k );

		return this;
	},

	// filter
	//   Reduce the set of matched elements to those that match the selector or pass the function's test 
	//   ( #id, .class, tagName )
	//
	// parameters
	//   _s : selector string (#id, .class, tagName)
	// return
	//   Cheese Object
	//
	// example
	//   .filter("#id .class DIV");
	filter : function ( _s )
	{
		if(!_s || typeof _s != "string")
			return this;

		var selectorItems = (Cheese.trim(_s.split(".").join(" .").split("#").join(" #"))).split( /\s+/ ),
			l = selectorItems.length,
			cArray = new Array(),
			j;
			
		for ( var i =0, e; e = this.dom(i); i++ )
		{	
			for( j = 0; j < l; j++)
				if( ( selectorItems[j].substr(0,1) == "#"  // if #id
					&& e.id != selectorItems[j].substring(1, selectorItems[j].length) ) 
				|| (selectorItems[j].substr(0,1) == "." // if class
					&& !Cheese(e).hasClass( selectorItems[j].substring(1, selectorItems[j].length) ) )
				|| ( selectorItems[j].substr(0,1) != "#" && // if tag name
					selectorItems[j].substr(0,1) != "." &&
					e.nodeName.toString().toUpperCase() != selectorItems[j].toUpperCase() ) )
					break;
					
			if ( j == l )
				cArray.push( e );
		}

		return Cheese(cArray);
	},

	
	// not
	//   exclude a component if it is selected
	not : function ( _s )
	{
		if( _s == undefined || _s == null )
			return this;
		else if ( typeof _s == "number" ) 
		{
			var cArray = new Array();
				
			for( var i = 0, e; e = this.dom(i); i++ )
				if( i != _s )
					cArray.push( e );
			
			return Cheese( cArray );			
		}
		else if ( typeof _s == "object" )
		{
			var cArray = new Array();
			
			for(var i = 0, e; e = this.dom(i); i++ )
				if( this.dom(i) != _s )
					cArray.push( e );
			
			return Cheese( cArray );
		}
		else if( typeof _s == "string" )
		{
			var selectorItems = (Cheese.trim(_s.split(".").join(" .").split("#").join(" #"))).split( /\s+/ ),
				l = selectorItems.length,
				cArray = new Array(),
				j;
		
			for ( var i =0, e; e = this.dom(i); i++ )
			{
				for( j = 0; j < l; j++)
					if( ( selectorItems[j].substr(0,1) == "#"  // if #id
						&& e.id == selectorItems[j].substring(1, selectorItems[j].length) ) 
					|| (selectorItems[j].substr(0,1) == "." // if class
						&& Cheese(e).hasClass( selectorItems[j].substring(1, selectorItems[j].length) ) )
					|| ( selectorItems[j].substr(0,1) != "#" && // if tag name
						selectorItems[j].substr(0,1) != "." &&
						e.nodeName.toString().toUpperCase() == selectorItems[j].toUpperCase() ) )
						break;
				
				if ( j == l )
					cArray.push( e );
			}
			
			return Cheese( cArray );
		}
		
		return this;
	},

	// clone
	// param
	// _deep : boolean , false : only element, true : elements + property
	// return 
	// Cheese Object
	//h clone 테스트코드
	//d $("#testClone").clone( false );
	//d $("#sComponent").clone( true );
	clone : function( _deep ) 
	{	
		var cArray = new Array();

		for(var i=0, e; e = this.dom(i); i++)
			cArray.push( this.dom().cloneNode( _deep ) );

		return Cheese( cArray );
	},

	// hasClass
	//   if all dom objects has _class,
	//
	// parameters
	//   _class : class name
	// return
	//    true(has) or false(doesn't have)
	hasClass : function ( _class )
	{
		if(_class == undefined)
			return true;

		var classNames = (_class || "").split( /\s+/ );
		for (var i =0; this.dom(i); i++)
			for(var j=0; j<classNames.length; j++)
				if( (" " + this.dom(i).className + " ").indexOf( " " + classNames[j] + " ") == -1)
					return false;

		return true;
	},

	// addClass
	//   Adds the specified class(es) to each of the set of matched elements.
	//
	// parameters
	//   _class : class name
	// return
	//   Cheese Object
	addClass : function ( _class )
	{
		var classNames = (_class || "").split( /\s+/ );

		for ( var i = 0; this.component(i); i++ )
		{
			var c = this.dom(i);

		    // if className doesn't exist
			if ( !c.className )
		    	c.className = Cheese.trim(_class);
		    // if exist
		    else
		    {
		    	var className = " " + c.className + " ", setClass = c.className;
		    	for ( var k = 0, cl = classNames.length; k < cl; k++ )
		    		if ( className.indexOf( " " + classNames[k] + " " ) < 0 )
		    			setClass += " " + classNames[k];

		    	c.className = Cheese.trim(setClass);
		    }
		}

		return this;
	},

	// removeClass
	//   Remove the class(es) from each element in the set of matched elements.
	//   argument : doesn't exist -> remove all classes.
	//
	// parameters
	//   _class : class name
	// return
	//   Cheese Object
	removeClass : function ( _class )
	{
		var classNames = (_class || "").split( /\s+/ );

		for ( var i = 0; this.component(i); i++ )
		{
			var c = this.dom(i);

		    if( !c.className || !_class)
				c.className = "";
		    else if( c.className )
		    {
		    	var className = (" " + c.className + " ").replace( /[\n\t]/g, " ");
		    	for ( var k = 0, cl = classNames.length; k < cl; k++ )
		    		className = className.replace(" " + classNames[k] + " ", " ");
		    	c.className = Cheese.trim( className );
		    }
		}

		return this;
	},

	// toggleClass
	//   Add or delete one or more classes from each element in the set of matched elements,
	//   has _class : delete _class
	//   doesn't _class : add _class.
	//
	// parameters
	//   _class : class name
	// return
	//   Cheese Object
	toggleClass : function ( _class )
	{
		if(_class==undefined)
			return this;

		var classNames = (_class || "").split( /\s+/ );
		for ( var i = 0; this.component(i); i++ )
		{
			var c = this.dom(i);

		    if( !c.className)
   				c.className = Cheese.trim(_class);
		    else
		    {
		    	for ( var k = 0, cl = classNames.length; k < cl; k++ )
		    	{
		    		if( Cheese(c).hasClass(classNames[k]) )
		    			Cheese(c).removeClass(classNames[k]);
		    		else
		    			Cheese(c).addClass(classNames[k]);
		    	}
		    }
		}

		return this;
	},

	//h _data 만 들어오면 _value 값 리턴
	//h 클래스에 CheeseGlobal.prefixBufferClass+ _data + "-"+ _value 값으로 저장
	//h 중간 구분자로 - 사용
	//h _data와 _value  값 모두 들어오면
	//h "CheeseData"+ _data + "-" + _value값으로 저장
	//h 따라서 공백 없어야하고 문자로만 이루어 져야 함
	//h 해당 처리 모듈도 들어가야 할듯 (들어가면안되는문자열 쳐내는 모듈)
	//h 중복되면 맨 처음에 있는 것만 저장
	//h ""이나 null이 _value 값으로 들어오면 값 삭제
	// bufferClass
	//   set or get data in element's className
	//
	// parameters
	//  _name : key
	//  _value : value
	//
	// return
	//  if _value doesn't exist
	// 	  the first matched element's value
	//  if _value exist
	//    Cheese Object
	bufferClass : function ( _name, _value )
	{
		var prefix = CheeseGlobal.prefixBufferClass + Cheese.trim(_name)+"-";

		if( arguments.length == 1)
		{
			var c = this.dom();

		    if( c && c.className )
		    {
		    	var classNames = (c.className || "").split( /\s+/ );
		    	for ( var i = 0; i<classNames.length; i++)
				{
		    		if ( classNames[i].substr(0,prefix.length) == prefix)
		    		{
		    			return classNames[i].substring(
		    				classNames[i].indexOf( prefix ) + prefix.length,
		    				classNames[i].length );
		    		}
		    	}
			}

			return "";
		}
		else if (arguments.length == 2)
		{
			var value = "";
			if( (_value!=null) && (_value != ""))
				value = Cheese.trim(_value);

			return this.each( function()
			{
				var classNames="";
		    	if( this.className )
		    	{
		    		classNames = (this.className || "").split( /\s+/ );
		    		for ( var i = 0; i<classNames.length; i++)
					{
		    			if ( classNames[i].substr(0, prefix.length) == prefix )
		    			{
		    				Cheese(this).removeClass(classNames[i]);
		    				if(value!="") Cheese(this).addClass(prefix+value);
		    				break;
		    			}
		    		}
		    	}

		    	if( !this.className || i == classNames.length )
		    		if(value!="") Cheese(this).addClass(prefix+value);
			});

		}

		return this;
	},

	// buffer
	//   set or get buffer data in object buffer space
	//
	// parameters
	//   _name : key
	//   _data : value (optional)
	// return
	//   if set : cheese Object
	//   if get : value
	buffer : function ( _name, _data )
	{
		//set mode 
		if( arguments.length == 2)
		{
			return this.each( function()
			{
	    		var classNames = (this.className || "").split( /\s+/ );
	    		for ( var i = 0; i<classNames.length; i++)
	    		{
	    			if ( classNames[i].substr(0,CheeseGlobal.prefixBufferID.length) == CheeseGlobal.prefixBufferID)
	    			{
	    				var bufferID = window.parseInt( classNames[i].substring(
	    						classNames[i].indexOf( CheeseGlobal.prefixBufferID ) + CheeseGlobal.prefixBufferID.length,
	    						classNames[i].length ) );
	    				CheeseGlobal.buffer[bufferID][_name] = _data;
	    				break;
	    			}
	    		}

	    		if( i == classNames.length )
	    		{
	    			var bufferID = ++CheeseGlobal.bufferID;
	    			CheeseGlobal.buffer[ bufferID ] = {};
	    			Cheese(this).addClass( CheeseGlobal.prefixBufferID + CheeseGlobal.bufferID );
	    			CheeseGlobal.buffer[bufferID][_name] = _data;
	    		}
	    	});
		}
		//get mode
		else if( arguments.length == 1)
		{
			var c = this.dom();

		   	if( c && c.className )
		   	{
		   		var classNames = (c.className || "").split( /\s+/ );
		   		for ( var i = 0; i<classNames.length; i++)
		   		{
		   			if ( classNames[i].substr(0,CheeseGlobal.prefixBufferID.length) == CheeseGlobal.prefixBufferID)
		   			{
		   				var bufferID = window.parseInt(classNames[i].substring(
		   					classNames[i].indexOf( CheeseGlobal.prefixBufferID ) + CheeseGlobal.prefixBufferID.length,
		   					classNames[i].length ));

		   				return CheeseGlobal.buffer[bufferID][_name];
		   			}
		   		}
		   	}
		    return "";
		}
	},

	// prev
	//   Get the immediately preceding sibling of each element in the set of matched elements, optionally filtered by a selector.
	//
	// parameters
	//   _s : selector string ( optional )
	// return
	//   Cheese Object
	prev : function( _s )
	{
		var cArray = new Array();

		for ( var i = 0, e; e = this.dom(i); i++ )
		{
			cArray[i] = e.previousSibling;

			while(cArray[i] && cArray[i].nodeType != 1)
				cArray[i] = cArray[i].previousSibling;
		}

		return Cheese( cArray ).filter( _s );
	},

	// next
	//   Get the immediately following sibling of each element in the set of matched elements, optionally filtered by a selector.
	//
	// parameters
	//   _s : selector string (optional)
	// retrun
	//   Cheese Object
	next : function( _s )
	{
		var cArray = new Array();

		for ( var i = 0, e; e = this.dom(i); i++ )
		{
			cArray[i] = e.nextSibling;

			while(cArray[i] && cArray[i].nodeType != 1)
				cArray[i] = cArray[i].nextSibling;
		}

		return Cheese( cArray ).filter(_s);
	},

	// parent
	//   Get the parent of each element in the current set of matched elements, optionally filtered by a selector.
	//
	// parameters
	//   _s : selector string (optional)
	// retrun
	//   Cheese Object 
	parent : function( _s )
	{
		var cArray = new Array();
		
		for (var i = 0, e; e = this.dom(i); i++ )
		{
			// remove duplicated nodes
			var j, l = cArray.length;
			
			for ( j=0; j < l; j++)
				if( cArray[j] == e.parentNode)
					break;

			if( j == l )
				cArray.push( e.parentNode  );
		}

		return Cheese( cArray ).filter(_s);
	},

	// contents
	//   Get the children of each element in the set of matched elements, including text and comment nodes.
	//
	// parameters
	//   _s : selector string (optional)
	// retrun
	//   Cheese Object 
	contents : function( _s )
	{
		var cArray = new Array();

		for(var i =0, e; e = this.dom(i); i++ )
		{
			for(var j = 0, l = e.childNodes.length; j < l; j++)
				cArray.push( e.childNodes[j] );
		}

		return Cheese( cArray ).filter( _s );
	},

	//h 치즈 오브젝트의 childNodes중, DOM Node Object 값만 리턴 ( NodeType 이 1인 것만 리턴 )
	//h NodeType의 값
	//h Element    Node.ELEMENT_NODE   1
	//h Text    Node.TEXT_NODE    3
	//h Document   Node.DOCUMENT_NODE   9
	//h Comment    Node.COMMENT_NODE   8
	//h DoucmentFragment Node.DOCUMENT_FRAGMENT_NODE 11
	//h Atter    Node.ATTRIBUTE_NODE   2
	// children
	//   Get the children of each element in the set of matched elements, optionally filtered by a selector.
	// 
	// parameters
	//   _s : selector string (optional)
	// retrun
	//   Cheese Object 
	children : function( _s )
	{
		var cArray = new Array();

		for(var i = 0, e; e = this.dom(i); i++ )
		{
			var childTemp = e.childNodes;
			for( var j =0; childTemp && childTemp[j]; j++ )
			{
				if ( childTemp[j].nodeType == 1 )
					cArray.push( childTemp[j] );
			}
		}

		return Cheese( cArray ).filter(_s);
	},

	// siblings
	//   Get the siblings of each element in the set of matched elements, optionally filtered by a selector.
	//
	// parameters
	//   _s : selector string (optional)
	// retrun
	//   Cheese Object 
	siblings : function ( _s )
	{
		var cArray = new Array();
		
		for ( var i = 0, e; e = this.dom(i); i++ )
		{			
			var p = e.previousSibling,
				n = e.nextSibling,
				tArray = new Array();
			
			// previous
			while( p )
			{
				if ( p.nodeType == 1)
				{
					var j,
						l = tArray.length;
				
					for( j = 0; j < l; j++)
						if ( tArray[j] == p )
							break;
					
					if( j == l)
						tArray.push(p);
				}
				
				p = p.previousSibling;
			}
			
			// reverse
			tArray.reverse();
			
			// next
			while( n )
			{
				if ( n.nodeType == 1)
				{
					var j,
						l = tArray.length;
				
					for( j = 0; j < l; j++)
						if ( tArray[j] == n )
							break;
					
					if( j == l)
						tArray.push(n);
				}
				
				n = n.nextSibling;
			}
			
			for( var j = 0; e = tArray[j]; j++)
			{
				var k,
					l = cArray.length;
				
				for( k = 0; k < l; k++)
					if ( cArray[k] == e )
						break;
					
				if( k == l)
					cArray.push(e);
			}
			
		}

		return Cheese( cArray ).filter( _s );
	},

	// eq
	//   Reduce the set of matched elements to the one at the specified index.
	//
	// parameters
	//   _idx : index (number)
	// return
	//   Cheese Object
	eq : function( _idx )
	{
		var cArray = new Array();

		var e = this.dom(_idx);
		if ( e )
			cArray.push( e );

		return Cheese( cArray );
	},
	
	// add
	add : function( _data )
	{
		if( typeof _data == "object" )
		{
			var cArray = new Array();
			
			for ( var i = 0, e; e = this.dom(i); i++ )
				cArray.push( e ) ;
			for ( var i = 0, e; e = _data.dom(i); i++ )
			{
				var j, tl = this.size();
				for ( j = 0; j < tl; j++ )
					if ( e == this.dom(j) )
						break;
						
				if( j == tl )
					cArray.push( e ) ;
			}
				
			return Cheese( cArray );
		}
		else if( typeof _data == "string" )
			return this.add( Cheese(_data) );
		
		return this;
	},


	//h 속성 이름만 들어오면 첫번째 엘리먼트 객체의 속성만 리턴
	//h 속성 내용도 같이 들어오면 모든 객체 설정
	// attr
	//   Get or set the value of an attribute for the first element in the set of matched elements.
	//
	// parameters
	//   _name : attribute name
	//   _attr : attribute value (optional)
	// 
	// return
	//   if _attr exists, attribute value for the first element
	//   else Cheese Object
	attr : function ( _name, _attr )
	{
		if( arguments.length == 1 )
			return (this.dom())?this.dom().getAttribute(_name):"";
		else if ( arguments.length == 2 )
			return this.each( function()
			{
				this.setAttribute( _name, _attr );
			} );
	},

	// dom
	//   return dom element
	//
	// parameters
	//  _idx : index   
	//
	// return
	//   _idx doesn't exist : the first dom element
	//   else the (_idx)th dom element
	dom : function ( _idx )
	{
		if(!_idx)
			_idx = 0;

		return ((!this.componentContext[_idx]) ? null : this.componentContext[_idx].elementContext);
	},

	// component
	//   return component object
	//
	// parameters
	//  _idx : index   
	//
	// return
	//   _idx doesn't exist : the first component object
	//   else the (_idx)th component object
	component : function ( _idx )
	{
		if(!_idx)
			_idx = 0;

		return (!this.componentContext[_idx]) ? null : this.componentContext[_idx];
	},


	//h 해당 형제 객체중에 몇번째 인지 알려주기
	// index
	//   Search for first matched element's index from among the sliblings.
	//
	// return
	//   index (number)
	index : function ()
	{
		var c = this.dom();

		var i = 0;
		while( c )
		{
			c = c.previousSibling;
			if(c && c.nodeType==1) i++;
		}

		return i;
	},

	// remove
	//   remove elements
	//
	// parameters
	//   dom objects
	//   index
	//   none : all object remove
	//
	// return
	//   Cheese Object
	remove : function( _val )
	{
		var removeFunc = function()
		{
			this.parentNode.removeChild(this);
		};
	
		//number
		if ( typeof _val == "number" )
		{
			this.eq(_val).each( removeFunc );
		}
		//dom element
		else if ( typeof _val =="object")
		{
			for(var i =0, e; this.dom(i); i++)
			{
				if(this.dom(i) == _val)
					this.eq(_val).each( removeFunc );
			}		
		}
		else
		{
			this.each( removeFunc );
		}
		
		return this;
	},

	// css
	//   Get or set the value of a style property for the element in the set of matched elements.
	//
	// parameters
	//   _object : array or string
	//   _style : style property (optional)
	//
	// return
	//   Cheese Object
	//   a style property for the first element ( if _style exists )
	//
	// example
	//   .css ( { "width" : "300px",
	//            "height' : "200px" } );
	//   .css ( "width", "300px" );
	//   .css ( "width" );
	css : function ( _object, _value )
	{
		if( arguments.length == 1 )
		{
			if( typeof _object == "object" )
			{
				for( var k in _object)
					this.css(k, _object[k] );

				return this;
			}
			else if( typeof _object == "string" )
			{
				var style = (_object == 'float') ? 'cssFloat' :Cheese.camelize(_object);
				var value = (this.dom())? this.dom().style[ style ] : null;
				if( !value || value=='auto' )
				{
					var css = document.defaultView.getComputedStyle(this.dom(), null);
					value = css ? css[style] : null;
				}
				
				return value;
			}
		}
		else if(arguments.length == 2)
		{
			return this.each( function()
			{
				if( this.style )
					this.style[ Cheese.trim(_object) ] = _value;
			});
		}

		return this;
	},
	
    top : function( _value )
	{
		if( !_value )
			if( this.dom() )
				return window.parseFloat(window.getComputedStyle(this.dom()).getPropertyValue("top"));
			else
				return null;

		return this.each( function()
		{
			Cheese(this).css("top", window.parseFloat(_value) + "px" );
		});
	},
	
	left : function( _value )
	{
		if( !_value )
			if( this.dom() )
				return window.parseFloat(window.getComputedStyle(this.dom()).getPropertyValue("left"));
			else
				return null;	

		return this.each( function()
		{
			Cheese(this).css("left", window.parseFloat(_value) + "px" );
		});
	},
	// width
	//   Get the current computed width for the first element in the set of matched elements.
	//   Set the CSS width of each element in the set of matched elements. ( if _value exists )
	width : function( _value )
	{
		if( !_value )
			if( this.dom() )
				return window.parseFloat(window.getComputedStyle(this.dom()).getPropertyValue("width"));
			else
				return null;

		return this.each( function()
		{
			Cheese(this).css("width", window.parseFloat(_value) + "px" );
		});
	},

	// height
	//   Get the current computed height for the first element in the set of matched elements.
	//   Set the CSS height of each element in the set of matched elements. ( if _value exists )
	height : function( _value )
	{
		if( !_value )
			if( this.dom() )
				return window.parseFloat(window.getComputedStyle(this.dom()).getPropertyValue("height"));
			else
				return null;

		return this.each( function()
		{
			Cheese(this).css("height", window.parseFloat(_value) + "px" );
		});
	},

	//h _htmlCode가 없을때, HTML 코드를 리턴한다.(string).
	//h _htmlCode가 있을 때, HTML 코드를 삽입 혹은 replace한다.
	//h
	//h _htmlCode != NULL 일 때는, 배열의 모든 요소에 대해 _htmlCode 로 replace() 한다.(each() 처럼 )
	//h	그리고 본인 객체를 리턴한다. (체인 메소드 위해)
	//h _htmlCode == NULL 일 때는, 배열의 첫 요소에 대해서만 html 코드를 리턴한다.
	// html
	//   Get or set the HTML contents of the element in the set of matched elements.
	html : function( _htmlCode )
	{
		if ( arguments.length == 0 )
			return (this.dom())?this.dom().innerHTML:"";
		else
			return this.each( function()
			{
				this.innerHTML = _htmlCode;
			});
	},
	
    //h _htmlCode가 없을때, HTML 코드를 리턴한다.(string).
	//h _htmlCode가 있을 때, HTML 코드를 삽입 혹은 replace한다.
	//h
	//h _htmlCode != NULL 일 때는, 배열의 모든 요소에 대해 _htmlCode 로 replace() 한다.(each() 처럼 )
	//h	그리고 본인 객체를 리턴한다. (체인 메소드 위해)
	//h _htmlCode == NULL 일 때는, 배열의 첫 요소에 대해서만 html 코드를 리턴한다.
    outerHTML : function( _htmlCode )
    {
        if ( arguments.length == 0 )
			return (this.dom())?this.dom().outerHTML:"";
		else
			return this.each( function()
			{
				this.outerHTML = _htmlCode;
			});    
    },

	//h 인자(텍스트)가 있으면 아래 내용을 해당을 텍스트로 설정
	//h 아니면 텍스트 노드의 내용만 리턴
	// text
	//   Set the content of each element in the set of matched elements to the specified text.
	//   Get the combined text contents of each element in the set of matched elements, including their descendants.
	text : function ( _text )
	{
		if( _text )
		{
			return this.each( function ()
			{
				Cheese(this).contents().remove();
				this.appendChild(document.createTextNode(_text));
			});
		}

		var cArray = new Array();
		for(var i=0; this.dom(i); i++)
			cArray.push(this.dom(i));

		return this.reText( cArray );
	},

	//h 텍스트 노드들을 얻기 위한 재귀호출 함수
	//h 자식이 있으면 그 자식을 처리하기 위해 재귀로 사용
	// reText
	//   it is recursive function to get a text node
	//   if the node has children, then call recursive function
	reText : function ( _cArray )
	{
		var rText = "";

		for ( var i =0;  _cArray[i]; i++ )
		{
			var c = _cArray[i];

			if ( c.nodeType === 3 || c.nodeType === 4 )
				rText += c.nodeValue;
			else if ( c.nodeType !== 8 )
				rText += this.reText( c.childNodes );
		}

		return rText;
	},

	// append
	//   Insert content to the end of each element in the set of matched elements.
	append : function ( _content )
	{
		return this.each( function()
		{	
			var cheeseThis = Cheese(this),
				cheeseThisContents = cheeseThis.contents(),
				cheeseThisContentsSize = cheeseThisContents.size();

			if( cheeseThisContentsSize == 0)
				cheeseThis.html(_content);
			else
				cheeseThisContents.eq( cheeseThisContentsSize-1 ).after(_content);
		});
	},

	// prepend
	//   Insert content, specified by the parameter, to the beginning of each element in the set of matched elements.
	prepend : function ( _content )
	{
		return this.each( function()
		{
			var cheeseThis = Cheese(this),
				cheeseThisContents = cheeseThis.contents();

			if( cheeseThisContents.size() == 0)
				cheeseThis.html(_content);
			else
				cheeseThisContents.eq().before(_content);
		});
	},

	// wrap
	//   Wrap an HTML structure around each element in the set of matched elements.
	wrap : function ( _content )
	{
		return this.each( function()
		{
			var divNode = document.createElement("div");
			divNode.innerHTML = _content;
			var contentNode = divNode.childNodes[0];

			var cloneNode = this.cloneNode(true);
			Cheese(this).parent().dom().replaceChild(cloneNode, this);
			contentNode.appendChild(this);

			Cheese(cloneNode).parent().dom().replaceChild(contentNode, cloneNode);
		});
	},

	// wrapAll
	//   Wrap an HTML structure around all elements in the set of matched elements.
	wrapAll : function( _content )
	{
		Cheese(this.dom()).wrap(_content);

		for( var i = 1; this.dom(i); i++)
			Cheese(this.dom()).parent().dom().appendChild(this.dom(i));

		return this;
	},

	// after
	//   Insert content, specified by the parameter, after each element in the set of matched elements.
	after : function ( _content )
	{
		return this.each( function()
		{
			var nextNode = this.nextSibling;
			var divNode = document.createElement("div");
			divNode.innerHTML = _content;
			
			// if this is last element (next node is null or undefiend) then insert last
			while(divNode.childNodes[0])
				Cheese(this).parent().dom().insertBefore(divNode.childNodes[0], nextNode);
		});
	},

	// before
	//   Insert content, specified by the parameter, before each element in the set of matched elements.
	before : function ( _content )
	{
		return this.each( function()
		{
			var divNode = document.createElement("div");
			divNode.innerHTML = _content;

			while(divNode.childNodes[0])
				Cheese(this).parent().dom().insertBefore(divNode.childNodes[0], this);
		});
	},

	// find
	//   Get the descendants of each element in the current set of matched elements, filtered by a selector.
	find : function ( _s )
	{
		var cArray = new Array();

		for(var i=0; this.dom(i); i++)
		{
			var tArray = this.dom(i).querySelectorAll(_s);
			for(var j=0; tArray[j]; j++)
				cArray.push(tArray[j]);
		}

		return Cheese(cArray);
	},

	//h 객체가 로드될 때 실행하는 함수를 지정한다.
	//h _func 가 없으면 함수 꺼짐
	// load
	//   bind a load function
	load : function ( _func )
	{
		return this.each(
			function()
			{
				if( !_func )
				{
					this.onload = null;
					return;
				}

				var loadFunc = this.onload;
				if( !loadFunc )
				{
					this.onload = _func;
					return;
				}

				var setFunc = function()
				{
					loadFunc.call(this);
					_func.call(this);
				}

				this.onload = setFunc;
			}
		);
	},
    
	//h _prop : animation의 원하는 css속성의 목표치를 설정해주는 부분.
	//h _time : animation에서 실행되는 시간을 설정해주는 부분.
	//h _func : animation이 실행되고난서 실행되는 함수.
	//h _preFunc : animation 실행되기전에 실행되는함수.
	animate : function(_prop, _time, _func, _preFunc)
    {   
        if(!_prop || !_time)
            return this;
        if(typeof _time != "number")
        {
            if(_time == "slow") _time = 1000;
            else if(_time == "nomal") _time = 600;
            else _time = 300;
        }
        if(!this.buffer("CheeseAnimateInitFlag")) 
        {
            var thisObject = this;
            this.buffer("CheeseAnimateStopFlag",false);
            this.buffer("CheeseAnimateInitFlag",true);    
            var timerCount = 0;
            this.buffer("CheeseAnimationTimerFirstSetting",true);    
            var popObj;
			Cheese.timer(function() 
			{(
		        function() 
		        {
			        if( this.buffer("CheeseAnimateStopFlag"))
					{ 
						Cheese.timer("CheeseAnimationTimer");
						this.buffer("CheeseAnimateStopFlag",false); 
						this.buffer("CheeseAnimateInitFlag",false);
						return;
					}							
						
					//h 새로운 에니메이션의 타이머 처음 시작시에 최초에 한번 불려진다.
					if(this.buffer("CheeseAnimationTimerFirstSetting"))
					{
					    popObj = Cheese.queue("CheeseAnimateQueue");
					    if(popObj == null)
					    {
					        Cheese.timer("CheeseAnimationTimer");
						    this.buffer("CheeseAnimateInitFlag",false);
						    return;
					    }
						if(popObj["pre"]) popObj["pre"].call(this); 
						var param = new Array(); 
						var risevalue = new Array(); 
						for(var p in popObj["prop"])
						{
							param[p] = window.parseFloat(this.css(p));
							risevalue[p] = (popObj["prop"][p] - param[p])/(popObj["time"] / 16.0); 
						}
						this.buffer("CheeseAnimationTimerParamInitValue",param);
						this.buffer("CheeseAnimationTimerParamRiseValue",risevalue);
						this.buffer("CheeseAnimationTimerFirstSetting",false);
					}
					for(var p in popObj["prop"])  
					{
						var str = this.css(p);
						if(str.indexOf("px") == -1) {str = "";}
						else {str = "px";}     
						
						if(this.buffer("CheeseAnimationTimerParamInitValue")[p] > popObj["prop"][p] ? (this.buffer("CheeseAnimationTimerParamRiseValue")[p] * timerCount + this.buffer("CheeseAnimationTimerParamInitValue")[p]) <= popObj["prop"][p] : (this.buffer("CheeseAnimationTimerParamRiseValue")[p] * timerCount + this.buffer("CheeseAnimationTimerParamInitValue")[p]) >= popObj["prop"][p])
						{
							this.css(p, popObj["prop"][p] + str);
							continue;
						}
						this.css(p, this.buffer("CheeseAnimationTimerParamRiseValue")[p] * timerCount + this.buffer("CheeseAnimationTimerParamInitValue")[p] + str);
					}
					timerCount++;
					if( this.buffer("CheeseAnimationTimerParamInitValue")[p] > popObj["prop"][p] ? parseFloat( this.css(p)) <= popObj["prop"][p] : parseFloat( this.css(p)) >= popObj["prop"][p]) 
					{     
						for(var p in popObj["prop"])       
						{
							var str = this.css(p);
							if(str.indexOf("px") == -1) str = "";
							else str = "px";	
							this.css(p, popObj["prop"][p] + str);
						}
						if(popObj["func"]) popObj["func"].call(this); 
						
						this.buffer("CheeseAnimationTimerFirstSetting",true); 
						timerCount = 0;
					}
				}
			).call( thisObject ); }, 16,"CheeseAnimationTimer");  
        }
        for(var p in _prop)
        {         
            if(typeof _prop[p] == "number")
                continue;
            var str = _prop[p];
            if(str.indexOf("px"))
            {
                 _prop[p] = str.substring(0,str.indexOf("px"));
            }
        }
        Cheese.queue({"prop":_prop,"time":_time,"func":_func,"pre":_preFunc},"CheeseAnimateQueue");
        return this;  
        // Cheese.queue  
    },     
    
    //h animation queue를 비우고 현재 실행중인 animation까지 실행시킨다.
    clearQueue : function()
    {
        Cheese.queue("clear","CheeseAnimateQueue");
        return this;
    },
    
    //h animation queue 를 비우고, 현재실행둥인 animation을 멈춘다.
    stop : function()
    {   
        Cheese.queue("clear","CheeseAnimateQueue");
        this.buffer("CheeseAnimateStopFlag",true);
        return this;
    },
    
    //h 객체의 투명도가 바뀌며 나타난다.
    //h _time : 실행되는 시간
    //h _func : 실행되고나서 실행되는 함수.
    fadeIn : function(_time,_func)
    {
        if(!this.buffer("CheeseEffectPreState"))
		{
		    if(this.css("display") == "none")
		    {   
		        this.css("display","block");
		        this.buffer("CheeseEffectPreState",{"absheight":this.css("height"),"abswidth":this.css("width"),"absdisplay":"none",
		        "height":this.css("height"),"width":this.css("width"),"display":"none" });       
		        this.css("display","none");
		    }
		    else this.buffer("CheeseEffectPreState",{"absheight":this.css("height"),"abswidth":this.css("width"),"absdisplay":this.css("display"),"height":this.css("height"),"width":this.css("width"),"display":this.css("display") });   
		}
		
        this.animate({"opacity":1.0},_time,_func,function(){
            if(this.css("display") == "none")
            {
                if(this.buffer("CheeseEffectPreState"))
                    this.css("display",this.buffer("CheeseEffectPreState")["absdisplay"]);
                else 
                    this.css("display","block");
            }
        }); 
        return this;
    },
    
    //h 객체의 투명도가 바뀌며 사라진다.
    //h _time : 실행되는 시간
    //h _func : 실행되고나서 실행되는 함수.
    fadeOut : function(_time,_func)
    {
        if(!this.buffer("CheeseEffectPreState"))
		{
		    if(this.css("display") == "none")
		    {   
		        this.css("display","block");
		        this.buffer("CheeseEffectPreState",{"absheight":this.css("height"),"abswidth":this.css("width"),"absdisplay":"none",
		        "height":this.css("height"),"width":this.css("width"),"display":"none" });       
		        this.css("display","none");
		    }
		    else this.buffer("CheeseEffectPreState",{"absheight":this.css("height"),"abswidth":this.css("width"),"absdisplay":this.css("display"),"height":this.css("height"),"width":this.css("width"),"display":this.css("display") });   
		}
        this.animate({"opacity":0.0},_time,
        function(){     
            this.css("display","none");
            if(_func)_func.call(this); 
        },function(){
            if(this.css("display") == "none")
            {
                if(this.buffer("CheeseEffectPreState"))
                    this.css("display",this.buffer("CheeseEffectPreState")["absdisplay"]);
                else 
                    this.css("display","block");
            }
        });      
        return this;
    },

	// show
	//   show DOM elements
	//h 객체의 투명도와 width, height 가 바뀌며 나타난다.
    //h _time : 실행되는 시간
    //h _func : 실행되고나서 실행되는 함수.
	show : function(_time, _func)
	{   
	    return this.each( function()
	    {
	        var thisObj = Cheese(this);
		    if(!thisObj.buffer("CheeseEffectPreState"))
		    {
		        if(thisObj.css("display") == "none")
		        {   
		            thisObj.css("display","block");
		            thisObj.buffer("CheeseEffectPreState",{"absheight":thisObj.css("height"),"abswidth":thisObj.css("width"),"absdisplay":"none",
		            "height":thisObj.css("height"),"width":thisObj.css("width"),"display":"none" });       
		            thisObj.css("display","none");
		        }
		        else thisObj.buffer("CheeseEffectPreState",{"absheight":thisObj.css("height"),"abswidth":thisObj.css("width"),"absdisplay":thisObj.css("display"),"height":thisObj.css("height"),"width":thisObj.css("width"),"display":thisObj.css("display") });   
		    }
		    
		    if(!_time)
	        {
		        if(thisObj.buffer("CheeseEffectPreState")["absdisplay"] == "none") 
		            thisObj.css("display","block");
		        else 
		            thisObj.css("display",thisObj.buffer("CheeseEffectPreState")["absdisplay"]);   
	            return this;	        
		    }
    		   
	        thisObj.animate({"height":thisObj.buffer("CheeseEffectPreState")["absheight"],"width":thisObj.buffer("CheeseEffectPreState")["abswidth"],"opacity":1.0 },
	        _time,function(){
	            thisObj.css("width",thisObj.buffer("CheeseEffectPreState")["abswidth"]);
	            thisObj.css("height",thisObj.buffer("CheeseEffectPreState")["absheight"]);
	            if(_func)_func.call(this); 
	        },function(){
	            if(thisObj.css("display") == "none") thisObj.css("display","block");
	            else
	            {
	                thisObj.css("display",thisObj.buffer("CheeseEffectPreState")["absdisplay"]); 
	            }
	            thisObj.css("width","0px");
	            thisObj.css("height","0px");
	            thisObj.css("opacity",0);
	        });   
		});
	},

	// hide
	//   hide DOM elements
	//h 객체의 투명도와 width, height 가 바뀌며 사라진다.
    //h _time : 실행되는 시간
    //h _func : 실행되고나서 실행되는 함수.
	hide : function(_time, _func)
	{   
	    return this.each( function()
	    {
	        var thisObj = Cheese(this);
	       
            if(!thisObj.buffer("CheeseEffectPreState"))
            {
                if(thisObj.css("display") == "none")
                {   
                    thisObj.css("display","block");
                    thisObj.buffer("CheeseEffectPreState",{"absheight":thisObj.css("height"),"abswidth":thisObj.css("width"),"absdisplay":"none",
                    "height":thisObj.css("height"),"width":thisObj.css("width"),"display":"none" });       
                    thisObj.css("display","none");
                }
                else thisObj.buffer("CheeseEffectPreState",{"absheight":thisObj.css("height"),"abswidth":thisObj.css("width"),"absdisplay":thisObj.css("display"),"height":thisObj.css("height"),"width":thisObj.css("width"),"display":thisObj.css("display") });   
            }
            if(!_time)
	        {
			    thisObj.css("display","none");
			    return this;
		    }
            
            thisObj.animate({"height":0,"width":0,"opacity":0 },
            _time,function(){
                thisObj.css("width",thisObj.buffer("CheeseEffectPreState")["abswidth"]);
	            thisObj.css("height",thisObj.buffer("CheeseEffectPreState")["absheight"]);
                thisObj.css("display","none");
                if(_func)_func.call(this); 
            },function(){
                if(thisObj.css("display") == "none") thisObj.css("display","block");
                else
                { 
                    thisObj.css("display",thisObj.buffer("CheeseEffectPreState")["absdisplay"]); 
                }
            });   
            
        });
	},
	
	//h 객체의 height 가 바뀌며 나타난다.
    //h _time : 실행되는 시간
    //h _func : 실행되고나서 실행되는 함수.
	slideDown : function(_time, _func)
	{
        if(!this.buffer("CheeseEffectPreState"))
		{
		    if(this.css("display") == "none")
		    {   
		        this.css("display","block");
		        this.buffer("CheeseEffectPreState",{"absheight":this.css("height"),"abswidth":this.css("width"),"absdisplay":"none",
		        "height":this.css("height"),"width":this.css("width"),"display":"none" });       
		        this.css("display","none");
		    }
		    else this.buffer("CheeseEffectPreState",{"absheight":this.css("height"),"abswidth":this.css("width"),"absdisplay":this.css("display"),"height":this.css("height"),"width":this.css("width"),"display":this.css("display") });   
		}
	    this.animate({"height":this.buffer("CheeseEffectPreState")["absheight"] },
	    _time,function(){
	        this.css("width",this.buffer("CheeseEffectPreState")["abswidth"]);
	        this.css("height",this.buffer("CheeseEffectPreState")["absheight"]);
	        if(_func)_func.call(this); 
	    },function(){
	        if(this.buffer("CheeseEffectPreState")["absdisplay"] == "none") this.css("display","block");
	        else this.css("display",this.buffer("CheeseEffectPreState")["absdisplay"]);
	        //d this.css("width","0px");
	        this.css("height",0);
	        this.css("width",this.buffer("CheeseEffectPreState")["abswidth"])
	        this.css("opacity",1);
	    });   
		return this;
	},

	//h 객체의 height 가 바뀌며 사라진다.
    //h _time : 실행되는 시간
    //h _func : 실행되고나서 실행되는 함수.
	slideUp : function(_time, _func)
	{
	    if(!this.buffer("CheeseEffectPreState"))
        {
            if(this.css("display") == "none")
            {   
                this.css("display","block");
                this.buffer("CheeseEffectPreState",{"absheight":this.css("height"),"abswidth":this.css("width"),"absdisplay":"none",
                "height":this.css("height"),"width":this.css("width"),"display":"none" });       
                this.css("display","none");
            }
            else this.buffer("CheeseEffectPreState",{"absheight":this.css("height"),"abswidth":this.css("width"),"absdisplay":this.css("display"),"height":this.css("height"),"width":this.css("width"),"display":this.css("display") });   
        }

        this.animate({"height":0 },
        _time,function(){
            this.css("width",this.buffer("CheeseEffectPreState")["abswidth"]);
            this.css("height",this.buffer("CheeseEffectPreState")["absheight"]);
            this.css("display","none");
            if(_func)_func.call(this); 
        },function(){
            if(this.buffer("CheeseEffectPreState")["absdisplay"] == "none") this.css("display","block");
            else this.css("display",this.buffer("CheeseEffectPreState")["absdisplay"]);
            this.css("opacity",1);
        });   
        return this;
	},	
	
	//h 순차적으로 slide 함수가 실행
	slideToggle : function(_time, _func)
	{
		if ( this.buffer("CheeseSlideToggleFunc") == "Func2" )
		{
			this.slideDown(_time,_func);
			this.buffer("CheeseSlideToggleFunc", "Func1" );
		}
		else
		{
			this.slideUp(_time,_func);
			this.buffer("CheeseSlideToggleFunc", "Func2" );
		}
		return this; 
	},


	//h 순차적으로 callback 함수가 실행
	// toggle
	//   bind toggle functions with elements.
	toggle : function ( _func1, _func2 )
	{
		return this.tap( function ()
		{
			if ( Cheese(this).buffer("CheeseToggleData") == "Func2" )
			{
				_func2.call(this);
				Cheese(this).buffer("CheeseToggleData", "Func1" );
			}
			else
			{
				_func1.call(this);
				Cheese(this).buffer("CheeseToggleData", "Func2" );
			}
		});
	},

	//h    배열.trigger( 이벤트 종류 )  배열 객체에 대해 순차적으로 [이벤트 종류] 를 실행.
	//h    "이벤트 종류"는 반드시 기존 존재 이벤트. custom event 는 못쓴다.
	//h    @ _existEventName : 이벤트 이름(문자열). ex: "touchend"
	//h    RETURN : this.
	//  trigger @_eventName to the DOM node elements.
	//  @_eventName : event name to trigger. ( only the artificial event )
    triggerExistEvent : function( _existEventName )
    {
		//d debug.log("triggerExistEvent() START ");
        var i = 0, t = null;
        var domObject = this.dom(i);
        while( domObject )
        {
            //h Handle triggering a single element
            //h don't do events on text and comment nodes
            //h if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { return undefined; }  
            domObject[ _existEventName ] && domObject[ _existEventName ]();  // Text 노드 등 클릭 이벤트가 Null or Undefined 경우를 상정
            domObject = this.dom(++i);
        };
		//d debug.log("triggerExistEvent() END ");
    	return this;
    },


	//h    배열.trigger( 이벤트 종류 )  배열 객체에 대해 순차적으로 [이벤트 종류] 를 실행.
	//h    "이벤트 종류"는 반드시 Artificial Event.
	//h    @ _customEventName : 이벤트 이름(문자열). ex: "TAP"
	//h    RETURN : this.
	//  trigger @_eventName to the DOM node elements.
	//  @_eventName : event name to trigger. ( only the artificial event ) 
    triggerCustomEvent : function( _customEventName )
    {
		//d debug.log("triggerCustomEvent() START ");
        var i = 0, t = null;
        var domObject = this.dom(i);
        while( domObject )
        {
            //h Handle triggering a single element
            //h don't do events on text and comment nodes
            //h if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { return undefined; } 
            domObject[ _customEventName ] && CheeseTouch.Send( _customEventName, domObject, "trigger", null );
            domObject = this.dom(++i);
        };
		//d debug.log("triggerCustomEvent() END ");
        return this;
    },

	//h    배열.trigger( 이벤트 종류 )  배열 객체에 대해 순차적으로 [이벤트 종류] 를 실행.
	//h    만일 배열 객체 중 [이벤트 종류]에 대해 이벤트 핸들러가 설정되어 있지 않으면, 실행되는 거 없다.
	//h    @ _eventName : 이벤트 종류.
	//h    RETURN : this.
	//h    .trigger( "click" )
	//  trigger @_eventName to DOM node elements.
	//  @_eventName : event name to trigger.
    trigger : function( _eventName )
    {
		//d debug.log(" trigger() START");
        if ( !_eventName ) {
            return this;
        }

        switch( _eventName )
        {
            case CheeseGlobal.EVENTSTRING.FLICK_LEFT :
            case CheeseGlobal.EVENTSTRING.FLICK_RIGHT :
            case CheeseGlobal.EVENTSTRING.FLICK_UP :
            case CheeseGlobal.EVENTSTRING.FLICK_DOWN :
            case CheeseGlobal.EVENTSTRING.TAP :
            case CheeseGlobal.EVENTSTRING.LONG_TAP :
            case CheeseGlobal.EVENTSTRING.DOUBLE_TAP :
            case CheeseGlobal.EVENTSTRING.TOUCH_START :
            case CheeseGlobal.EVENTSTRING.TOUCH_START :
            case CheeseGlobal.EVENTSTRING.TOUCH_MOVE :
            case CheeseGlobal.EVENTSTRING.TOUCH_END :
                //h 이벤트 이름이 Custom event 일 경우는, CheeseTouch.Send() 로 CustomEvent를 실행시켜야 한다.
				// use the artificial event ( ex: TAP ).
                this.triggerCustomEvent( _eventName );
                //h customEvent[ "touchEnd" ] = touch[ _eventName ].call( this );
                return this;
            default :
                //h 이벤트 이름이 Custom Event 가 아닐 경우는, 기존처럼 addEventListener 를 이용하거나, domObject.eventName() 의 형태로 실행하면 된다.
				// use the existed event ( ex: onfocus ).
                this.triggerExistEvent( _eventName );
        }
		//d debug.log(" trigger() END2");
        return this;
    },

	// attach the existed events to the domObject.
    //	@domObject : DOM node elements for event handling.
    primaryEventRegist : function( domObject )    
    {
		if( CheeseGlobal.eventType == "touch" )
		{
			domObject.addEventListener( "touchstart", CheeseTouch.onTouchEvent, false );
	        domObject.addEventListener( "touchmove", CheeseTouch.onTouchEvent, false );
		    domObject.addEventListener( "touchend", CheeseTouch.onTouchEvent, false );
		}
		else
		{
			domObject.addEventListener( "mouseup", CheeseTouch.onTouchEvent, false );
			domObject.addEventListener( "mousemove", CheeseTouch.onTouchEvent, false );
			domObject.addEventListener( "mousedown", CheeseTouch.onTouchEvent, false );
		}
	},
	
	//h 객체의 event가 disable되었을때 사용되는 함수로, event를 enable 시켜준다.
	
	/*
	this.EVENTSTRING = {
        FLICK_LEFT :    "FLICKLEFT"     ,
        FLICK_RIGHT :   "FLICKRIGHT"    ,
        FLICK_UP :       "FLICKUP"      ,
        FLICK_DOWN :     "FLICKDOWN"    ,
        DRAG :           "DRAG"			,
        DRAG_DROP : 	 "DRAGDROP"   	,
        SWIPE :		     "SWIPE"		,
        TAP :            "TAP" 			,
        LONG_TAP :       "LONGTAP"     	,
        DOUBLE_TAP :     "DOUBLETAP"   	,
        TOUCH_START :    "TOUCHSTART"   ,
        TOUCH_MOVE :     "TOUCHMOVE"   	,
        TOUCH_END :      "TOUCHEND"
    };
	*/
    enableEvent : function( _event )
    {
        if(_event == CheeseGlobal.EVENTSTRING.DRAG_DROP )
        {
            var eventType = this.buffer("CheeseSaveEvent");
            eventType[CheeseGlobal.EVENTSTRING.TOUCH_END] = true;
            eventType[CheeseGlobal.EVENTSTRING.DRAG] = true;
            this.buffer("CheeseSaveEvent",eventType);
            return this;
        }
        if(_event == CheeseGlobal.EVENTSTRING.SWIPE)
        {
            var eventType = this.buffer("CheeseSaveEvent");
            eventType[CheeseGlobal.EVENTSTRING.FLICK_RIGHT] = true;
            eventType[CheeseGlobal.EVENTSTRING.FLICK_LEFT] = true;
            eventType[CheeseGlobal.EVENTSTRING.DRAG] = true;
            this.buffer("CheeseSaveEvent",eventType);
            return this;
        }
        var eventType = this.buffer("CheeseSaveEvent");
        eventType[_event] = true;
        this.buffer("CheeseSaveEvent",eventType); 
        return this;
    },
    //h 객체의 event를 disable 시켜준다. 
    disableEvent : function( _event )
    {
        if(_event == CheeseGlobal.EVENTSTRING.DRAG_DROP )
        {
            var eventType = this.buffer("CheeseSaveEvent");
            eventType[CheeseGlobal.EVENTSTRING.TOUCH_END] = false;
            eventType[CheeseGlobal.EVENTSTRING.DRAG] = false;
            this.buffer("CheeseSaveEvent",eventType);
            return this;
        }
        if(_event == CheeseGlobal.EVENTSTRING.SWIPE)
        {
            var eventType = this.buffer("CheeseSaveEvent");
            eventType[CheeseGlobal.EVENTSTRING.FLICK_RIGHT] = false;
            eventType[CheeseGlobal.EVENTSTRING.FLICK_LEFT] = false;
            eventType[CheeseGlobal.EVENTSTRING.DRAG] = false;
            this.buffer("CheeseSaveEvent",eventType);
            return this;
        }
        var eventType = this.buffer("CheeseSaveEvent");
        eventType[_event] = false;
        this.buffer("CheeseSaveEvent",eventType);
        return this;
    },
    
    drag : function( _fnEventHandle )
    {
        this.addEventByType( CheeseGlobal.EVENTSTRING.DRAG, CheeseTouch.dragMove);
        this.buffer("CheeseDragEventFunc",_fnEventHandle);
        return this;
    },
    
    flickLeft : function( _fnEventHandle )
    {
        this.addEventByType( CheeseGlobal.EVENTSTRING.FLICK_LEFT, _fnEventHandle);
        return this;
    },

    flickRight : function( _fnEventHandle )
    {
        this.addEventByType( CheeseGlobal.EVENTSTRING.FLICK_RIGHT, _fnEventHandle);
        return this;
    },

    flickUp : function( _fnEventHandle )
    {
        this.addEventByType( CheeseGlobal.EVENTSTRING.FLICK_UP, _fnEventHandle);
        return this;
    },

    flickDown : function( _fnEventHandle )
    {
        this.addEventByType( CheeseGlobal.EVENTSTRING.FLICK_DOWN, _fnEventHandle );
        return this;
    },

    tap : function( _fnEventHandle )
    {
        this.addEventByType( CheeseGlobal.EVENTSTRING.TAP, _fnEventHandle);
        return this;
	},
	
    //h _touchTime : long tap이 걸리는 기준시간을 설정. 설정안할경우에 default 값이 들어간다.
	longTap : function( _fnEventHandle, _touchTime )
    {
        this.addEventByType( CheeseGlobal.EVENTSTRING.LONG_TAP, _fnEventHandle);
        if(!_touchTime) this.buffer("CheeseLongTapTime",CheeseGlobal.TouchTimer.longTap);
        else this.buffer("CheeseLongTapTime",_touchTime);
        return this;
    },

    doubleTap : function( _fnEventHandle )
    {
        this.addEventByType( CheeseGlobal.EVENTSTRING.DOUBLE_TAP, _fnEventHandle);
        return this;
    },

    touchStart : function( _fnEventHandle )
    {
        this.addEventByType( CheeseGlobal.EVENTSTRING.TOUCH_START, _fnEventHandle);
        return this;
    },

    touchMove : function( _fnEventHandle )
    {
        this.addEventByType( CheeseGlobal.EVENTSTRING.TOUCH_MOVE, _fnEventHandle);
        return this;
    },

    touchEnd : function( _fnEventHandle )
    {
        this.addEventByType( CheeseGlobal.EVENTSTRING.TOUCH_END, _fnEventHandle);
        return this;
    },
    
    //h _isFlickEnd (boolean) : swipe시에 swipe객체를 감싸는 box객체를 넘을지 안넘을지 선언해주는 부분.
    //                          true일경우 box객체를 넘을수없다.
    //h _verlocityPercent (intger) : swipe시 자동으로 움직일때, 움직이는 속도를 설정해주는 부분.
	swipe : function(_isFlickEnd ,_verlocityPercent,_fnEventHandle )
	{	
		this.addEventByType( CheeseGlobal.EVENTSTRING.DRAG , CheeseTouch.dragForSwipe);		
		this.addEventByType( CheeseGlobal.EVENTSTRING.FLICK_RIGHT, CheeseTouch.flickForSwipe);
		this.addEventByType( CheeseGlobal.EVENTSTRING.FLICK_LEFT,  CheeseTouch.flickForSwipe);
		
		this.buffer("CheeseSwipeFunc",_fnEventHandle);
		this.buffer("CheeseSwipeVerlocityPercent",_verlocityPercent);
		this.buffer("CheeseSwipeIsSwipeEnd",_isFlickEnd);
		return this;
	},
	//h _isFillMode (boolean) : drag 객체가 drop객체에 어느정도나 들어가야 event가 발생하는지 설정해주는 부분. 
	//                          true일경우 drag 객체가 drop객체에 모두 들어가야 event가 발생한다. 
	//h _dripObj (Cheese) : drop 객체를 정해준다. 복수개도 가능하다.
	dragDrop : function( _fnEventHandle, _isFillMode ,_dropObj )
	{
		this.addEventByType( CheeseGlobal.EVENTSTRING.DRAG, CheeseTouch.dragforDragDrop);
		this.addEventByType( CheeseGlobal.EVENTSTRING.TOUCH_END, CheeseTouch.touchUpforDragDrop);

		var dropObj = new Array(); 
		for(var i = 2;i < arguments.length;i++)
		{
			dropObj.push(arguments[i]);
		}
		this.buffer("CheeseDragDropEventFunc",_fnEventHandle);
		this.buffer("CheeseDragDropMode",_isFillMode);
		this.buffer("CheeseDragDropArrayObj",dropObj); 
		return this;
	},

	// attach @_fnEventHandle to the domObject with @_eventType event.
	// @ _eventType : artificial Event Name.
	// @ _fnEventHandle : event handler name ( function )
    addEventByType : function( _eventType, _fnEventHandle) 
    {
		var i = 0;
        var domObject = this.dom(i);
        while( domObject )
        {
            this.primaryEventRegist( domObject );
            CheeseTouch.AddEvent( CheeseTouch, _eventType, domObject, _fnEventHandle );
            domObject = this.dom(++i);
        }
        this.addClass("handsPointer");
    },
    
    //h swipe의 경우에만 사용되는 함수로서 매소드호출시에 swipe의 움직임이 멈춘다.
    swipeEventStop : function()
    {
        this.buffer("CheeseSwipeEventStop",true);
        return this;
    },

	// set
	//	component function
	//	set component
	set : function( )
	{
		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().set)
				c.component().set.call(this);
		});
	},

	// data
	//	component function
	//	set component's data
	data : function( _value )
	{
		if( arguments.length == 0 )
		{
			if(this.component().data)
				return this.component().data.apply(this.dom());

			return null;
		}
		
		var args = arguments;
		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().data)
				c.component().data.apply(this, args);
		});
	},

	count : function ()
	{
		if(this.component().count)
			return this.component().count.apply(this.dom());

		return null;
	},
	
	// go
	//	component function
	go : function( )
	{
		var args = arguments;

		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().go)
				c.component().go.apply(this, args);
		});
	},
	
	// rss
	//	component function
	rss : function( _url )
	{
		var args = arguments;

		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().rss)
				c.component().rss.apply(this, args);
		});
	},

	// rssCache
	//	component function
	rssCache : function( )
	{
		var args = arguments;

		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().rssCache)
				c.component().rssCache.apply(this, args);
		});
	},
	

	// func
	//	component function
	func : function()
	{
		var args = arguments;

		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().func)
				c.component().func.apply(this, args);
		});
	},
	
	// viewFunc
	//	component function
	viewFunc : function()
	{
		var args = arguments;

		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().viewFunc)
				c.component().viewFunc.apply(this, args);
		});
	},
	
	// sub
	//	component function
	sub : function()
	{
		var rCheese = Cheese();
			
		for ( var i = 0, l = this.size(); i < l; i++ )
			if( this.component(i).sub )
				rCheese = rCheese.add ( this.component(i).sub.apply(this.dom(i), arguments) );

		return rCheese;
	},
	
	// refresh
	//	component function
	refresh : function()
	{
		var args = arguments;

		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().refresh)
				c.component().refresh.apply(this, args);
		});
	},

	// autoRefresh
	//	component function
	autoRefresh : function()
	{
		var args = arguments;

		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().autoRefresh)
				c.component().autoRefresh.apply(this, args);
		});
	},

	// enablePage
	//	component function
	enablePage : function( )
	{
		var args = arguments;

		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().enablePage)
				c.component().enablePage.apply(this, args);
		});
	},	

	// disablePage
	//	component function
	disablePage : function( )
	{
		var args = arguments;

		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().disablePage)
				c.component().disablePage.apply(this, args);
		});
	},	

	// addPage
	//	component function
	addPage : function( _url )
	{
		var args = arguments;

		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().addPage)
				c.component().addPage.apply(this, args);
		});
	},

	// option
	//	component function
	//	set each component's option
	option : function( _value )
	{
		var args = arguments;

		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().option)
				c.component().option.apply(this, args);
		});
	},

	// removeItem
	//	component function
	removeItem : function( _value )
	{
		var args = arguments;

		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().removeItem)
				c.component().removeItem.apply(this, args);
		});
	},
	
	// execFunc
	//	component function
	execFunc : function( _value )
	{
		var args = arguments;

		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().execFunc)
				c.component().execFunc.apply(this, args);
		});
	},

	//h 해당 컴포넌트 데이터
	//h 첫번째 것만 반환
	// select
	//	component function
	//	set component selected data or return component selected data
	select : function( _value )
	{
		if( arguments.length == 0 )
		{
			if(this.component().select)
				return this.component().select.apply(this.dom());

			return null;
		}
		
		var args = arguments;
		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().select)
				c.component().select.apply(this, args);
		});
	},	
	
	// chart component
	clicked : function( _value )
	{
		var args = arguments;        
		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().clicked)
				c.component().clicked.apply(this, args);
		});
	},
	
	chartDraw : function( _width, _height )
	{
		var args = arguments;        
		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().chartDraw)
				c.component().chartDraw.apply(this, args);
		});
	},
	chartAnimation : function( _width, _height , _time , _func )
	{
		var args = arguments;        
		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().chartAnimation)
				c.component().chartAnimation.apply(this, args);
		});
	},

	
	
	// zoom
	//	component function
    //	google map component part
    zoom : function( _zoom )
	{
	    if( arguments.length == 0 )
		{
			if(this.component().zoom)
				return this.component().zoom.apply(this.dom());

			return null;
		}
		
		var args = arguments;
    
		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().zoom)
				c.component().zoom.apply(this, args);
		});
	},

	// center
	//	component function
    //	google map component part
	center : function( _lat , _lng  )
	{
	    if( arguments.length == 0 )
		{
			if(this.component().center)
				return this.component().center.apply(this.dom());

			return null;
		}
		
		var args = arguments;
    
		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().center)
				c.component().center.apply(this, args);
		});
	},

	// addMarker
	//	component function
    //	google map component part	
	addMarker : function( _data )
	{
		var args = arguments;
		return this.each( function()
		{
		    
			var c = Cheese(this);
			if(c.component().addMarker)
				c.component().addMarker.apply(this, args);
		});
	},

	// removeMarker
	//	component function
    //	google map component part
	removeMarker : function( _data )
	{
		var args = arguments;
    
		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().removeMarker)
				c.component().removeMarker.apply(this, args);
		});
	},

	// getMarker
	//	component function
    //	google map component part
	getMarker : function( _data )
	{
		var args = arguments;
    
		if(this.component().getMarker)
			return this.component().getMarker.apply(this.dom(), arguments);

		return null;
	},
	
	// addOverlay
	//	component function
    //	google map component part	
	addOverlay : function( _data )
	{
		var args = arguments;
    
		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().addOverlay)
				c.component().addOverlay.apply(this, args);
		});
	},

	// removeOverlay
	//	component function
    //	google map component part
	removeOverlay : function( _data )
	{
		var args = arguments;
    
		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().removeOverlay)
				c.component().removeOverlay.apply(this, args);
		});
	},

	// getOverlay
	//	component function
    //	google map component part
	getOverlay : function( _data )
	{
		var args = arguments;
    
		
		if(this.component().getOverlay)
			return this.component().getOverlay.apply(this.dom(), arguments);

		return null;
	},
	
	// addCircle
	//	component function
    //	google map component part
	addCircle : function( _data )
	{
		var args = arguments;
    
		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().addCircle)
				c.component().addCircle.apply(this, args);
		});
	},

	// removeCircle
	//	component function
    //	google map component part
	removeCircle : function( _data )
	{
		var args = arguments;
    
		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().removeCircle)
				c.component().removeCircle.apply(this, args);
		});
	},

	// getCircle
	//	component function
    //	google map component part
	getCircle : function( _data )
	{
		var args = arguments;
    
		
		if(this.component().getCircle)
			return this.component().getCircle.apply(this.dom(), arguments);

		return null;
	},
	
	// addLine
	//	component function
    //	google map component part	
	addLine : function( _data )
	{
		var args = arguments;
    
		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().addLine)
				c.component().addLine.apply(this, args);
		});
	},

	// removeLine
	//	component function
    //	google map component part
	removeLine : function( _data )
	{
		var args = arguments;
    
		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().removeLine)
				c.component().removeLine.apply(this, args);
		});
	},

	// getLine
	//	component function
    //	google map component part
	getLine : function( _data )
	{
		var args = arguments;
    
		if(this.component().getLine)
			return this.component().getLine.apply(this.dom(), arguments);

		return null;
	},

	// addEvent
	//	component function
    //	google map component part
	addEvent : function( _data )
	{
		var args = arguments;
    
		
		if(this.component().addEvent)
			return this.component().addEvent.apply(this.dom(), arguments);

		return null;
	},

	// removeEvent
	//	component function
    //	google map component part
	removeEvent : function( _data )
	{
		var args = arguments;
    
		
		if(this.component().removeEvent)
			return this.component().removeEvent.apply(this.dom(), arguments);

		return null;
	},

	// getMap
	//	component function
    //	google map component part
	getMap : function( _data )
	{
		var args = arguments;
    
		if(this.component().getMap)
			return this.component().getMap.apply(this.dom(), arguments);

		return null;
	},

	// writeMark
	//	component function
    //	google map component part
	writeMark: function( _data, _func )
	{
		var args = arguments;
        
		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().writeMark)
				c.component().writeMark.apply(this, args);
		});
	},

	// writeLine
	//	component function
    //	google map component part
	writeLine : function( _data, _func )
	{
		var args = arguments;
        
		return this.each( function()
		{
			var c = Cheese(this);
			if(c.component().writeLine)
				c.component().writeLine.apply(this, args);
		});
	},

	componentContext : null,
	length : 0
};

//h string trim 해주는 함수
// trim
// Remove the whitespace from the beginning and end of a string.
Cheese.trim = function ( _s )
{
	return _s.replace(/^\s+|\s+$/g, "");
};

//h 스트링 camelize 해주는 함수
//h abc-eee -> abcEee
Cheese.camelize = function ( _s )
{
	return _s.replace(/-+(.)?/g, function(match, chr) {
		return chr ? chr.toUpperCase() : '';
    });
};

Cheese.openURL = function ( _url )
{
	if( Cheese.isWidget() )
		widget.openURL(_url);
	else
		window.location.href = _url;

	return true;
};

Cheese.toID = function ( _str )
{
	var strTrim = Cheese.trim(_str);
	
	return (strTrim.substr(0,1) == "#" ) ? strTrim : "#" + strTrim;
};


//h navigation 기능 페이지로 가기
//h #id 혹은 id 로 접근
//h 글로벌 변수엔 # 붙인것까지 저장
//h option 값으론
//h  transEffect
//h  transMotion
//h  transSecond
//h  transFunc
Cheese.go = function( _page, _option  )
{
	var page = Cheese.toID(_page),
		pageCheese = Cheese( page );
	
	if( pageCheese.size()!=0 && pageCheese.component().type == "popup" )
		return Cheese.pop.apply(this, arguments);
	else
		return Cheese.scene.go.apply(this, arguments);
};

//h navigation 기능
//h 뒤로 가기
Cheese.back = function( _option )
{
	return Cheese.scene( _option );
};


Cheese.scene = function(_scene, _option)
{
	if( typeof _scene == "object" || typeof _scene =="undefined" ) 
		return Cheese.scene.back.apply(this, arguments);
	else 
		return Cheese.scene.go.apply(this, arguments);
};

Cheese.scene.go = function ( _scene, _option )
{
	//h 인자 값 체크
	var scene = Cheese.toID(_scene);
	if( scene == "#idle" )
	{
		if( Cheese.isWidget() ) 
			Cheese.resize(CheeseGlobal.widgetIdleWidth, CheeseGlobal.widgetIdleHeight);
			
		Cheese(".widgetWrap").hide();
		Cheese(scene).show();
		CheeseGlobal.sceneStack = new Array();
		CheeseGlobal.sceneStack.push( [ scene, null ] );
		return true;
	}

	if( CheeseGlobal.pageCache == true )
		Cheese.storage("CheesePageCacheData", scene);
	if( Cheese.isWidget() ) 
		Cheese.resize();
			
	var curScene = CheeseGlobal.sceneStack.pop();
	//h 똑같은 씬 일때
	if(curScene[0] == scene)
	{
		CheeseGlobal.sceneStack.push(curScene);
		return true;
	}
	
	//h setList 있을때 소프트 키 변경
	var cheeseScene = Cheese(scene),
		cheeseSceneSetList = cheeseScene.find('.setList');
	if( cheeseSceneSetList.size() > 0 )
	{
		CheeseGlobal.setListSelectData = cheeseSceneSetList.select();
		Cheese.softkey( CheeseGlobal.softkeySetListData );
		Cheese.softkey( CheeseGlobal.softkeySetListFunc );
		Cheese(".setTitle").show();
		Cheese(".title").hide();
	}
	else if ( Cheese(scene).buffer("CheeseSceneComponentDataSoftkey") )
	{
		Cheese.softkey( Cheese(scene).buffer("CheeseSceneComponentDataSoftkey") );
		Cheese.softkey( CheeseGlobal.softkeyFuncGlobal );
	}
	else
	{
		Cheese.softkey( CheeseGlobal.softkeyDataGlobal );
		Cheese.softkey( CheeseGlobal.softkeyFuncGlobal );
		Cheese(".title").show();
		Cheese(".setTitle").hide();
	}

	// rssTime
	var strTime = "",
		cheeseSceneTab = cheeseScene.find('.tab'),
		cheeseSceneTabList = cheeseSceneTab.sub().find(".list"),
		cheeseScenePC = cheeseScene.find('.pageControl'),
		cheeseScenePCList =cheeseScenePC.sub().find(".list"),
		cheeseSceneList = cheeseScene.find(".list");

	if( cheeseSceneTabList.buffer("CheeseListComponentDataRSSFlag") )
		Cheese.rssTime( cheeseSceneTabList.buffer("CheeseListComponentDataRSSTime") );
	else if( cheeseScenePCList.buffer("CheeseListComponentDataRSSFlag") )
		Cheese.rssTime( cheeseScenePCList.buffer("CheeseListComponentDataRSSTime") );
	else if ( ( cheeseSceneTab.size() == 0 )
			&& ( cheeseScenePC.size() == 0  )
			&&  cheeseSceneList.buffer("CheeseListComponentDataRSSFlag") )
		Cheese.rssTime( cheeseSceneList.buffer("CheeseListComponentDataRSSTime") );
	else
		Cheese.rssTime();

	Cheese(".widgetWrap").show();
	Cheese.softkey.moreOff();
	Cheese.adjustSceneSize();

	//h 아무것도 안떠있을 때
	if( !curScene )
	{
		Cheese(scene).show();
		CheeseGlobal.sceneStack.push( [scene, null] );
		return true;
	}	
	//h 떠 잇던것이 idle이면
	else if( curScene[0] == "#idle" )
	{
		Cheese(curScene[0]).hide();
		Cheese(scene).show();
		CheeseGlobal.sceneStack.push(curScene);
		CheeseGlobal.sceneStack.push( [scene, null] );
		return true;
	}
	
	// option setting
	var option = new Array();
	for(var k in _option)
		option[k] = _option[k];
	if( !option.transEffect ) option.transEffect = CheeseGlobal.transEffect;
	if( !option.transSecond ) option.transSecond = CheeseGlobal.transSecond;
	if( !option.transMotion ) option.transMotion = CheeseGlobal.transMotion;
	option.transDirection = "on";

	Cheese.transition( Cheese(scene), Cheese(curScene[0]), option );

	option.transDirection = null;
	option.transFunc = null;
	CheeseGlobal.sceneStack.push( curScene);
	CheeseGlobal.sceneStack.push( [scene, option] );

	return true;
}

Cheese.scene.back = function ( _option )
{		
	//h 팝업 떠있으면 끄고 마침
	if( CheeseGlobal.pop )
	{
		Cheese.pop();
		return true;
	}
		
	//h 현재 scene 이름 들고 오기
	var curScene = CheeseGlobal.sceneStack.pop();
	var backScene = CheeseGlobal.sceneStack.pop();
	
	//h 뒷 scene가 없거나 idle일 경우
	if( !backScene || backScene[0] == "#idle" )
	{
		//h idle가 있다면
		if(Cheese("#idle").size() != 0)
		{
			Cheese(curScene[0]).hide();
			Cheese.go("idle");
		}
		//h 더이상 뒤 로 갈 곳이 없을 때
		else
			CheeseGlobal.sceneStack.push(curScene);
			
		return true;
	}
	
	//h setList 있을때 소프트 키 변경
	var cheeseScene = Cheese(backScene[0]),
		cheeseSceneSetList = cheeseScene.find('.setList');
	if( cheeseSceneSetList.size() > 0 )
	{
		CheeseGlobal.setListSelectData = cheeseSceneSetList.select();
		Cheese.softkey( CheeseGlobal.softkeySetListData );
		Cheese.softkey( CheeseGlobal.softkeySetListFunc );
		Cheese(".setTitle").show();
		Cheese(".title").hide();
	}
	else if ( Cheese(backScene[0]).buffer("CheeseSceneComponentDataSoftkey") )
	{
		Cheese.softkey( Cheese(backScene[0]).buffer("CheeseSceneComponentDataSoftkey") );
		Cheese.softkey( CheeseGlobal.softkeyFuncGlobal );
	}
	else
	{
		Cheese.softkey( CheeseGlobal.softkeyDataGlobal );
		Cheese.softkey( CheeseGlobal.softkeyFuncGlobal );
		Cheese(".title").show();
		Cheese(".setTitle").hide();
	}

	// rssTime
	var strTime = "",
		cheeseSceneTab = cheeseScene.find('.tab'),
		cheeseSceneTabList = cheeseSceneTab.sub().find(".list"),
		cheeseScenePC = cheeseScene.find('.pageControl'),
		cheeseScenePCList =cheeseScenePC.sub().find(".list"),
		cheeseSceneList = cheeseScene.find(".list");

	if( cheeseSceneTabList.buffer("CheeseListComponentDataRSSFlag") )
		Cheese.rssTime( cheeseSceneTabList.buffer("CheeseListComponentDataRSSTime") );
	else if( cheeseScenePCList.buffer("CheeseListComponentDataRSSFlag") )
		Cheese.rssTime( cheeseScenePCList.buffer("CheeseListComponentDataRSSTime") );
	else if ( ( cheeseSceneTab.size() == 0 )
			&& ( cheeseScenePC.size() == 0  )
			&&  cheeseSceneList.buffer("CheeseListComponentDataRSSFlag") )
		Cheese.rssTime( cheeseSceneList.buffer("CheeseListComponentDataRSSTime") );
	else
		Cheese.rssTime();

	Cheese.softkey.moreOff();
	Cheese.adjustSceneSize();	
	
	// option setting
	var appOption = (_option)?_option:curScene[1],
		option = new Array();
	for(var k in appOption)
		option[k] = appOption[k];
	if( !option.transEffect ) option.transEffect = CheeseGlobal.transEffect;
	if( !option.transSecond ) option.transSecond = CheeseGlobal.transSecond;
	if( !option.transMotion ) option.transMotion = CheeseGlobal.transMotion;
	option.transDirection = "off";

	Cheese.transition(  Cheese(backScene[0]), Cheese(curScene[0]), option );
	CheeseGlobal.sceneStack.push(backScene);

	return true;
}

Cheese.pop = function(_pop, _option)
{
	if( typeof _pop == "object" || typeof _pop =="undefined" ) 
		return Cheese.pop.back.apply(this, arguments);
	else 
		return Cheese.pop.go.apply(this, arguments);		
};

Cheese.pop.go = function ( _pop, _option )
{
	//h 인자 값 체크
	var pop = Cheese.toID(_pop);
	
	//h 소프트키 모어 끔
	Cheese.softkey.moreOff();

	
	//h 팝업 떠있으면 끔
	if( CheeseGlobal.pop )
		Cheese.pop();

	Cheese.softkey.moreOff();	
	Cheese(".blackBlank").show();

	// option setting
	var option = new Array();
	for(var k in _option)
		option[k] = _option[k];
	if( !option.transEffect ) option.transEffect = CheeseGlobal.popTransEffect;
	if( !option.transSecond ) option.transSecond = CheeseGlobal.popTransSecond;
	if( !option.transMotion ) option.transMotion = CheeseGlobal.popTransMotion;
	option.transDirection = "on";

	Cheese(pop).show();
	Cheese.transition( Cheese(pop).children(".popCon"), null, option );
	
	option.transDirection = null;
	option.transFunc = null;
	CheeseGlobal.pop = [pop, option];

	return true;
}

Cheese.pop.back = function ( _option )
{
	// 없 으면 	
	if( !CheeseGlobal.pop )
		return true;

	//h 인자값 체크
	var pop = CheeseGlobal.pop[0];	
	Cheese.softkey.moreOff();
	
	// option setting
	var appOption = (_option)?_option:CheeseGlobal.pop[1],
		option = new Array();
	for(var k in appOption)
		option[k] = appOption[k];
	if( !option.transEffect ) option.transEffect = CheeseGlobal.popTransEffect;
	if( !option.transSecond ) option.transSecond = CheeseGlobal.popTransSecond;
	if( !option.transMotion ) option.transMotion = CheeseGlobal.popTransMotion;
	option.transDirection = "off";
	option.transFunc = function () {
		Cheese(".blackBlank").hide();

		if( _option && _option.transFunc)
			_option.transFunc();
	}
	
	Cheese.transition( null, Cheese(pop).children(".popCon"), option );
	CheeseGlobal.pop = null;

	return true;
}

// Cheese Object Transition Function
// _on : Cheese Object that will be showed
// _off : Cheese Object that will be hided
// _opts : option
Cheese.transition = function ( _on, _off, _opts )
{
	var effect = null,
		motion = null,
		second = null,
		direction = null,
		func = null;
	
	for (var k in _opts)
	{
		if( k == "transEffect" ) effect = _opts[k];
		else if( k == "transSecond" ) second = _opts[k];
		else if( k == "transMotion" ) motion = _opts[k];
		else if( k == "transDirection" ) direction = _opts[k];
		else if( k == "transFunc" ) func = _opts[k];
	}			
	
	if( !effect ) effect = CheeseGlobal.transEffect;
	if( !second ) second = CheeseGlobal.transSecond;
	if( !motion ) motion = CheeseGlobal.transMotion;
	if( !direction ) direction = CheeseGlobal.transDirection;
	
	if( effect == "none" )
	{
		if ( _off ) _off.hide();
		if ( _on ) _on.show();
		if( func ) func();

		return true;
	}

	if ( direction == "on" ) direction = "On";
	else if ( direction == "off" ) direction = "Off";

	Cheese(".whiteBlank").show();
	
	if( _off )
	{
		_off.addClass( effect + direction + "Cur");
		_off.css("-webkit-animation-timing-function", motion );
		_off.css("-webkit-animation-duration", second );

	}
	
	if( _on )
	{
		_on.show();
		_on.addClass( effect + direction + "App");
		_on.css("-webkit-animation-timing-function", motion );
		_on.css("-webkit-animation-duration", second );
	}
	
	window.setTimeout(
		function(){
		
			if( _off )
			{
				_off.hide();
				_off.removeClass(effect + direction + "Cur");
				_off.css("-webkit-animation-duration", "" );
				_off.css("-webkit-animation-timing-function", "" );
			}
					
			if( _on )
			{
				_on.removeClass(effect + direction + "App");
				_on.css("-webkit-animation-duration", "" );
				_on.css("-webkit-animation-timing-function", "" );
			}
			
			Cheese(".whiteBlank").hide();
			
			if( func )
				func();
		},
		window.parseFloat(second)*1000);

	return true;
}


//h 현재 작동이 PC에서 하고 있는지, 아님 핸폰에서 하고 있는지 판단
// detects the widget-workign-status( on PC or on phone ).
// the phone is not comfortable to check the touch function, match the "mouseevent" with "touchevent" for simple test on desktop.
Cheese.isWidget = function ( )
{
	//d debug.log( "isPCState() : " + typeof widget );
	// the widget object exist == phone.  not exist == Desktop
	//h 위젯 객체가 있으면 핸드폰, 없으면 PC다.
	return ( typeof widget == "undefined" ) ? false : true;  
};


//h 현재 페이지의 사이즈를 줄인다.
//h 위젯 객체아 있으면 위젯의 사이즈를 줄이고
//h 없으면 걍 윈도우 사이즈 줄임
//h 인자가 하나도 들어와 있지 않으면
//h 위젯 활성화 크기인 480, 800으로 변경
// resize
// resize window
Cheese.resize = function ( _width, _height )
{
	if(arguments.length == 0)
	{
		_width = 480;
		_height = 800;
	}
	
	if( Cheese.isWidget() )
	{
		widget.window.resizeWindow(_width, _height);
	}
	else
	{
		window.resizeTo(_width, _height);
	}

	return true;
}

//h 화면을 리프레시 한다
Cheese.refresh = function ()
{
	window.location.reload();

	return true;
}

//Cheese storage
//save data on device
//save cookie, perference if possible
//if return value exist, return peference value
//if preference value doesn't exist, return cookie value
Cheese.storage = function ( _key, _value, _date )
{
	if( !_key ) {
		return null;
	}

	if(arguments.length == 2 || arguments.length == 3)
	{
		if( Cheese.isWidget() ) Cheese.storage.preference( _key, _value );
		else Cheese.storage.cookie( _key, _value, _date );

		return true;
	}
	else if(arguments.length == 1 )
	{
		if( Cheese.isWidget() ) return Cheese.storage.preference(_key);
		else return Cheese.storage.cookie( _key );
	}
};

//save data by using perference function
Cheese.storage.preference = function (_key, _value)
{
	if ( !Cheese.isWidget() || !_key )
	{
		return null;
	}

	if ( arguments.length == 1 )
		return widget.preferenceForKey( _key );
	else if( arguments.length == 2 )
		return widget.setPreferenceForKey( _value, _key );
}

//save data by using cookie
Cheese.storage.cookie = function ( _key, _value, _date )
{
	if ( !_key )
		return null;

	if( arguments.length == 1)
	{
		var cookieStr = document.cookie;
		if( cookieStr.length >= 0 )
		{
			var cookieStart = cookieStr.indexOf( _key );
			if( cookieStart >= 0)
			{
				cookieStart += _key.length;
				var cookieEnd = cookieStr.indexOf( ";", cookieStart );
				cookieEnd = (cookieEnd >= 0 )? cookieEnd : cookieStr.length;
				return unescape(cookieStr.substring(cookieStart + 1, cookieEnd));
			}
		}
	}
	else if( arguments.length == 2 || arguments.length == 3 )
	{
		var expString = "";
		if ( _date || (_date = CheeseGlobal.storageDate) )
		{
			var expTime = new Date();
			expTime.setDate(expTime.getDate() + window.parseInt(_date));
			expString = "expires="  +  expTime.toGMTString() +";";
		}

		document.cookie = _key + "=" + escape(_value) + "; path=/;" + expString;

	}
};

//global setting function
//two style argument
//Cheese.option ( { "key" : "value",
//                 "key2" : ["value1", "value2"] );
//Cheese.option ( "key", "value" );
//Cheese.option ( "key", ["value1", "value2"] );
Cheese.globalSetting =  Cheese.option = function( )
{
	var setting = {};

	//if first argument is string
	if(typeof arguments[0] == "string")
		setting[ arguments[0] ] = arguments[1];
	else if(typeof arguments[0] == "object")
		setting = arguments[0];

	for(var k in setting)
	{
		if( k == "transEffect" || k == "transSecond"  || k == "transMotion" 
			|| k == "popTransEffect" || k == "popTransSecond"  || k == "popTransMotion" 
			|| k =="softkeySetListData"  ||  k =="softkeySetListFunc" || k == "languageData" || k == "language" )
		{
			CheeseGlobal[k] = setting[k];
		}
		else if(k =="theme" )
		{
			CheeseGlobal.theme = setting[k];
			var cssLink = Cheese('head').children('link').each(
				function()
				{
					if ( Cheese(this).attr('href').indexOf('theme.css') != -1 )
						Cheese(this).remove();
				});
		
			if( CheeseGlobal.theme != "none" )
				Cheese('head').append('<link rel="stylesheet" href="theme/'+CheeseGlobal.theme+'/theme.css" type="text/css">');
		}		
		else if( k == "softkeyType" || k == "softkeyFunc" || k == "softkeyData" )
		{
			if( setting[k] == "none" || k == "softkeyData" )
				CheeseGlobal.softkeyDataGlobal = setting[k];
			if( k == "softkeyFunc" )
				CheeseGlobal.softkeyFuncGlobal = setting[k];

			Cheese.softkey(setting[k]);
		}
		else if (k=="softkeyMore")
		{
			if( setting[k] == "on") Cheese.softkey.moreOn();
			else Cheese.softkey.moreOff();
		}
		else if( k =="name" )
		{
			CheeseGlobal.name = setting[k];
		}
		else if ( k =="eventType" )
		{
			CheeseGlobal.eventType = setting[k];
		}
		else if( k == "pageCache" )
		{
			if( setting[k] == true && Cheese.storage("CheesePageCacheData") )
				Cheese.go ( Cheese.storage("CheesePageCacheData") );
			
			CheeseGlobal.pageCache = setting[k];
		}
	}

	return true;
};

//h softkey 
//h argument로 오브젝트가 들어오면 데이터 배열이라고 인식
//h argument로 function이 들어오면 백키에 들어갈 펑션이라고 인식
//h arugment로 문자열이 들어오면 타입이라고 인식(type1, type2)
Cheese.softkey = function ()
{
	if( Cheese(".softkey").size() == 0 )
		Cheese('.scenes').after('<div class="softkey"></div>');
	
	for( var i = 0; arguments[i]; i++ )
	{
		// softkey data
		if( typeof arguments[i] == "object" )
		{
			CheeseGlobal.softkeyData = arguments[i];
		}
		// softkey type
		else if( typeof arguments[i] == "string" )
		{
			if( arguments[i] == "none" )
			{
				Cheese('.softkey').remove();
				break;
			}
			CheeseGlobal.softkeyType = arguments[i];
		}
		// softkey function
		else if ( typeof arguments[i] == "function" )
		{
			CheeseGlobal.softkeyFunc = arguments[i];
		}

		Cheese(".softkey").data( CheeseGlobal.softkeyData, CheeseGlobal.softkeyType, CheeseGlobal.softkeyFunc  );
	}
	
	Cheese.adjustSceneSize();

	return true;
}

Cheese.softkey.moreOff = function()
{
	if( Cheese('.softkey.type1 ul.moreList').size() !=0 && Cheese('.softkey.type1 ul.moreList').css('bottom') == '70px')
	{
		var morekeyHeight = Math.abs(70-Cheese('.softkey.type1 ul.moreList').height());
		Cheese('.softkey.type1 ul.moreList').css('bottom','-'+morekeyHeight+'px');
	}	
	else if( Cheese('.softkeyType2 .btnOpen').size()!=0  )
	{
		Cheese('.softkeyType2 .btnOpen').parent().css('top',"0px");
		Cheese('.softkeyType2 .btnOpen').children('.softImg').removeClass('open');
	}

	return true;
}

Cheese.ajax = function ( _url, _fnSuccess, _option )
{
	return new CheeseAJAX( _url, _fnSuccess, _option  );
}

Cheese.xml = function ( _url, _fnSuccess, _opts  )
{
	if( arguments.length == 2 && typeof _url =="string" && typeof _fnSuccess == "object")
	{
		var opts = _fnSuccess,
			funcLoad = opts["load"],
			funcAttach = opts["attach"],
			funcOpts = opts["option"];

		return new CheeseXML( _url, function( _xml, _xmlObject, _xmlString ){
			var r;
			if( typeof funcLoad  == "function" )
				r = funcLoad.call(_xml, _xml, _xmlObject, _xmlString );
			if ( typeof funcAttach == "function" )
				funcAttach.call(_xml, r );
		}, funcOpts  );
	}
	else return new CheeseXML( _url, _fnSuccess, _opts  );
}

//h window 가 로드 되었을 때의 함수 설정
//h cheese의 load 함수 불러옴
// bind a load function
Cheese.load = function( _func ) 
{
	Cheese(window).load(_func);

	return true;
};

//d x = Cheese.noConflict();
//d x("abcd").,,,
Cheese.noConflict = function ()
{
	window.$ = CheeseGlobal.$;

	return Cheese;
};

Cheese.now = function ( )
{
	var	timeCur = new Date();
	
	return (1900 + timeCur.getYear()) + "-" + (1 + timeCur.getMonth()) + "-" + timeCur.getDate() + " " + timeCur.getHours() + ":" + timeCur.getMinutes();
};

Cheese.rssTime = function ( _str )
{
	if( arguments.length == 1 )
	{
		Cheese(".rssTime").show();
		Cheese(".rssTime").html(_str);
	}
	else
	{
		Cheese(".rssTime").hide();
		Cheese(".rssTime").html("");
	}

	return true;
};

Cheese.rssTime.on = function ( )
{
	Cheese(".rssTime").show();

	return true;
};

Cheese.rssTime.off = function ( )
{
	Cheese(".rssTime").hide();

	return true;
};

Cheese.adjustSceneSize = function ()
{
	// Scene Height Controller
	var h = 16; // Margin-top

	//h Title 처리. Scene 의 Top POsition 에도 영향을 준다.
	if(Cheese('.widgetWrap').find('.title').size() != "0" && Cheese('.widgetWrap').find('.title').css('display') != "none"){
		var titleH = Cheese('.widgetWrap').find('.title').height();
		h = h + titleH;

		Cheese('.widgetWrap').find('.scenes').css('top',h+"px");
	}

	if(Cheese('.widgetWrap').find('.setTitle').size() != "0" && Cheese('.widgetWrap').find('.setTitle').css('display') != "none"){
		var setTitleH = Cheese('.widgetWrap').find('.setTitle').height();
		h = h + setTitleH;
		Cheese('.widgetWrap').find('.scenes').css('top',h+"px");
	}

	if(Cheese('.widgetWrap').find('.softkey').size() != "0" && Cheese('.widgetWrap').find('.softkey').css('display') != "none")
		h = h + Cheese('.widgetWrap').find('.softkey').height();

	if(Cheese('.widgetWrap').find('.rssTime').size() != "0" && Cheese('.widgetWrap').find('.rssTime').css('display') != "none")
		h = h + Cheese('.widgetWrap').find('.rssTime').height();

	var sceneH = 762-h+"px"; //h 762px는 위젯 최대 높이

	Cheese('.widgetWrap').find('.scenes').css('height',sceneH);
	Cheese('.widgetWrap').find('.scene').css('height',sceneH);
	Cheese('.widgetWrap').find('.sceneBackground').css('height',sceneH);
	Cheese('.widgetWrap').find('.sceneWrap').css('height',sceneH);

	//Subscene
	var tabH = window.parseInt(Cheese('.tab').css('height'))+window.parseInt(Cheese('.tab').css('border-top-width'))+window.parseInt(Cheese('.tab').css('border-bottom-width'))+window.parseInt(Cheese('.tab').css('padding-top'))+window.parseInt(Cheese('.tab').css('padding-bottom'))+window.parseInt(Cheese('.tab').css('margin-bottom'))+window.parseInt(Cheese('.tab').css('margin-top')),
		 pcH = window.parseInt(Cheese('.pageControl').css('height'))+window.parseInt(Cheese('.pageControl').css('border-top-width'))+window.parseInt(Cheese('.pageControl').css('border-bottom-width'))+window.parseInt(Cheese('.pageControl').css('padding-top'))+window.parseInt(Cheese('.pageControl').css('padding-bottom'))+window.parseInt(Cheese('.pageControl').css('margin-bottom'))+window.parseInt(Cheese('.pageControl').css('margin-top')),
		 tabSubSceneH = window.parseInt(sceneH)-tabH,
		 pcSubSceneH = window.parseInt(sceneH)-pcH;

	 Cheese('.tab').parent().find('.subScene').css('height',tabSubSceneH+"px");
	 Cheese('.pageControl').parent().find('.subScene').css('height',pcSubSceneH+"px");

	 return true;
}

//h xpath로 검색한 결과를 cheese로 싸 주어 리턴하여, cheese의 filter, each 등을 사용할 수 있게 하자.
//d var getAllDataByXPathReturnCheese = function ( _xml, _queryString, _xPathResultType ) { 
Cheese.xpathSelector = function ( _xml, _queryString, _xPathResultType ) { 

	if ( !_xml || typeof( _xml ) != 'object' )
	{
		return null;
	}

	var resultType = _xPathResultType;
	
	if ( typeof( _xPathResultType ) != 'number' )
	{
		resultType = XPathResult.ANY_TYPE;
	}
	var xpath = _xml.evaluate( _queryString, _xml, null, resultType, null );

	switch( xpath.resultType )
	{
		case xpath.NUMBER_TYPE :
			return xpath.numberValue;
		case xpath.STRING_TYPE :
			return xpath.stringValue;			
		case xpath.BOOLEAN_TYPE :
			return xpath.booleanValue;			
		default :
			break;
	}

	//h 여기까지 왔다는 건, 값이 배열 집합이란 거다.
	//h 그냥 array로 묶어 준 다음, cheese로 넘기면 된다.
	var rv = new Array();
	var nodes = null; 

	while ( nodes = xpath.iterateNext() )
	{
		rv.push( nodes );
	}

	return Cheese( rv );
}

//h xpath 로 검색한 결과를, xpath로 넘겨준다.
//h 결과값을 조작하려면, iterateNext()를 사용해 값을 조작해야 한다. 
//d var getAllDataByXPathReturnXPath = function ( _xml, queryString, _xPathResultType ) 
Cheese.xpath = function ( _xml, queryString, _xPathResultType ) 
{ 
	if ( !_xml || typeof( _xml ) != 'object' )
	{
		return null;
	}

	var resultType = _xPathResultType;
		
	if ( typeof( _xPathResultType ) != 'number' )
	{
		resultType = XPathResult.ANY_TYPE;
	}
	var xpath = _xml.evaluate( queryString, _xml, null, resultType, null );

	switch( xpath.resultType )
	{
		case xpath.NUMBER_TYPE :
			return xpath.numberValue;
		case xpath.STRING_TYPE :
			return xpath.stringValue;
		case xpath.BOOLEAN_TYPE :
			return xpath.booleanValue;
		default :
			break;
	}

	return xpath;
}

//h XML로 검색한 결과를 cheese로 싸 주어 리턴하여, cheese의 filter, each 등을 사용할 수 있게 하자.
//var Cheese.XML.getAllDataByQuerySelectorReturnCheese = function ( _xml, _queryString, _xPathResultType ) 
//var getDataBySelectorReturnCheese = function ( _xml, _queryString ) 
Cheese.xmlSelector = function ( _xml, _queryString ) 
{ 

	if ( !_xml || typeof( _xml ) != 'object' || !_xml.documentElement )
	{
		return null;
	}

	var rv = new Array();
	var len = 0;
	var t3 = _xml.documentElement.querySelectorAll( _queryString );

	if( (len = t3.length) < 0 &&  (len = (_xml.getElementsByTagName( _queryString )).length) < 0 )
		return Cheese();

	for( var lp = 0; lp < len; lp++ )
	{
		rv.push( t3[ lp ] );
	}

	return Cheese( rv );
};

Cheese.reduceString = function ( _str, _num )
{
	if( typeof _str == "string" )
	{
		var num = ( typeof _num == "number" )?_num: 
			(( typeof _num == "string" )?window.parseInt(_num):
				CheeseGlobal.reduceStringNum);

		return (_str.length > num)?_str.substring(0,num-3)+"...":_str;
	}

	return null;
};

Cheese.extend = function ( _name, _function )
{
	if( typeof _name == "object" )
		for ( var k in _name )
			Cheese.extend(k, _name[k]);

	else if (typeof _name == "string" && typeof _function == "function" )
		Cheese.fn[_name] = _function;
		
	return true;
};

Cheese.alert = function ( _str, _opts )
{
	var opts = {};

	//d opts.okFunc = function(){ Cheese.back(); };
	opts.cancelFunc = function(){ Cheese.back(); };
	for ( var k in _opts )
		opts[k] = _opts[k];
	opts.html = _str;
		
	Cheese("#alert").data( opts );
	if( !(CheeseGlobal.pop && CheeseGlobal.pop[0] == "#alert")  ) Cheese.go("alert");

	return true;
};

//h timer를 관리하기 쉽게 함든 함수.
//h _func : timer 실행시에 실행되는 함수.
//h _time : timer 함수가 실행되는 주기
//h _id   : timer 를 쉽게관리하기 위해 사용하는 id, id값은 꼭 넣어줘야한다.
//h Cheese.timer(_id) 이런식으로 사용할경우 timer삭제
Cheese.timer = function( _func, _time, _id )
{
    if(arguments.length == 1 && typeof arguments[0] =="string")
    {
		if ( CheeseGlobal.timerList[_func] )
		{
			clearInterval( CheeseGlobal.timerList[_func] );
			CheeseGlobal.timerList[_func] = null;
		}

		return true;
    }
	else if ( typeof _func == "number")
	{
		clearInterval( _func );

		for( var k in CheeseGlobal.timerList )
		{
			if( CheeseGlobal.timerList[k] == _func )
				CheeseGlobal.timerList[k] = null;
		}

		return true;
	}
    else if( typeof _func == "function" )
    {  
		if( _id && CheeseGlobal.timerList[_id])
			Cheese.timer(_id);
        var count = 0; 
        var ti = ( _time ) ? setInterval(function(){ _func.call(this, ++count);},_time) : setTimeout(_func, 0);
		if( _id) CheeseGlobal.timerList[_id] = ti;

		return ti;
    }
};

Cheese.queue = function( _data, _id )
{
    if( _data == "clear") 
    {  
        CheeseGlobal.queueList[_id] = null; 
        return;
    }
    if(arguments.length == 1)
    {        
        if(typeof arguments[0] != "string" || !CheeseGlobal.queueList[_data])
            return null; 
        if(CheeseGlobal.queueList[_data].length != 0)
        {   
            var queue = CheeseGlobal.queueList[_data];
            queue.reverse();
            var reValue = queue.pop();
            queue.reverse();
            CheeseGlobal.queueList[_data] = queue;
            return reValue;
        }
        else 
            return null;
    }
    if(!CheeseGlobal.queueList[_id])
    {
        var queue = new Array();
        queue.push(_data);
        CheeseGlobal.queueList[_id] = queue;
    }
    else
    {
        var queue = CheeseGlobal.queueList[_id];
        queue.push(_data);
        CheeseGlobal.queueList[_id] = queue;
    }
};

Cheese.globalize = function() 
{
    if(!CheeseGlobal.languageData)
        return true;

    if(!CheeseGlobal.language )
        return;

	//처음에 국가코드받아오기
    var countryCode = CheeseGlobal.language;
    var codeIndex = -1;

   
    for( var i = 0;i<CheeseGlobal.languageData[0].length;i++)
        if(CheeseGlobal.languageData[0][i] == countryCode)
            codeIndex = i;
    
    if(codeIndex == -1)
        return;
    var divObj = Cheese('body').find("*");

    for(var i = 0;divObj.dom(i);i++)
    {
        if(!divObj.dom(i).firstChild)
            continue;
        if(Cheese(divObj.dom(i)).hasClass("noML"))
            continue;
        if(divObj.dom(i).firstChild.nodeValue == " " || divObj.dom(i).firstChild.nodeValue == null)
            continue; 
        //d 변역을 원하지 않거나 text가 없을경우에 
        var finalString = Cheese.deleteSpaceEnter(divObj.dom(i).firstChild.nodeValue);
        if(finalString == "" || finalString == null)
            continue; 

        for(var j = 1; j < CheeseGlobal.languageData.length ;j++)  
        {
            if( Cheese.trim(finalString) == CheeseGlobal.languageData[j][0])
                divObj.dom(i).firstChild.nodeValue = CheeseGlobal.languageData[j][codeIndex + 1];
        }                
    }
};

Cheese.getGrobalString = function ( _string )
{
    if(!CheeseGlobal.language)
        return;
        
    var countryCode = CheeseGlobal.language;
    var codeIndex;
    for( var i = 0;i<CheeseGlobal.languageData[0].length;i++)
        if(CheeseGlobal.languageData[0][i] == countryCode)
            codeIndex = i;
    if(!codeIndex)
        return;
    
    
    for(var j = 1; j < CheeseGlobal.languageData.length ;j++)  
    {
        if(_string == CheeseGlobal.languageData[j][0])
           return CheeseGlobal.languageData[j][codeIndex + 1];
    } 
}

Cheese.deleteSpaceEnter = function ( _string )
{
    var checkFlag = true;
    var convertFlag = false;
    var startIndex = 0;
    var endIndex = 0;
    for(var i = 0 ; i < _string.length;i++)
    {
        if(checkFlag)
        {
            if(_string[i] == " " || _string[i] == "\n")
            {
                convertFlag = true;
                continue;
            }
            else 
            {
                startIndex = i;
                checkFlag = false;
            }  
        }
        else 
        {
            if(_string[i] == "\n")
            {
                endIndex = i;
                convertFlag = true;
            }
        }
    }
    if(convertFlag)
    {
        return _string.slice(startIndex,endIndex);
    }
    else 
        return _string;
}



Cheese.fn.selector.prototype = Cheese.fn;
window.Cheese = window.$ = Cheese;
window.CheeseGlobal = CheeseGlobal;

document.write("<script src=component.js ></script>");
document.write("<script src=componentSetting.js ></script>");
document.write("<script src=cheeseTouch.js ></script>");
document.write("<script src=cheeseAJAX.js ></script>");
document.write("<script src=cheeseXML.js ></script>");
document.write("<script src=cheeseWidget.js></script>");

}
)(window);


